Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi =================================================================== @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:69 @ }; }; + sram: sram@00200000 { + compatible = "mmio-sram"; + reg = <0x00200000 0x4000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:932 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00300000 0x100000>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&ohci_clk>, <&ohci_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9260.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9260.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9260.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:72 @ }; }; + sram0: sram@002ff000 { + compatible = "mmio-sram"; + reg = <0x002ff000 0x2000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:964 @ }; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; + watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:982 @ atmel,idle-halt; status = "disabled"; }; + + gpbr: syscon@fffffd50 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd50 0x10>; + status = "disabled"; + }; }; nand0: nand@40000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1012 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x100000>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&ohci_clk>, <&ohci_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9261.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9261.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9261.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:63 @ }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x28000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x100000>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&ohci_clk>, <&hclk0>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&ohci_clk>, <&hclk0>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:836 @ clocks = <&mck>; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; + status = "disabled"; + }; + watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + gpbr: syscon@fffffd50 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd50 0x10>; + status = "disabled"; + }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9263.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9263.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9263.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:65 @ }; }; + sram0: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x14000>; + }; + + sram1: sram@00500000 { + compatible = "mmio-sram"; + reg = <0x00500000 0x4000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:690 @ }; }; + can { + pinctrl_can_rx_tx: can_rx_tx { + atmel,pins = + <AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* CANRX, conflicts with IRQ0 */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* CANTX, conflicts with PCK0 */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:926 @ clock-names = "pwm_clk"; status = "disabled"; }; + + can: can@fffac000 { + compatible = "atmel,at91sam9263-can"; + reg = <0xfffac000 0x300>; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can_rx_tx>; + clocks = <&can_clk>; + clock-names = "can_clk"; + }; + + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; + status = "disabled"; + }; + + rtc@fffffd50 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd50 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; + status = "disabled"; + }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x50>; + status = "disabled"; + }; }; fb0: fb@0x00700000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:966 @ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fb>; + clocks = <&lcd_clk>, <&lcd_clk>; + clock-names = "lcdc_clk", "hclk"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:993 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00a00000 0x100000>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&ohci_clk>, <&ohci_clk>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&ohci_clk>, <&ohci_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g15.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g15.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g15.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:10 @ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_lcd.dtsi" / { model = "Atmel AT91SAM9G15 SoC"; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g15ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g15ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g15ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:11 @ */ /dts-v1/; #include "at91sam9g15.dtsi" +#include "at91sam9x5dm.dtsi" #include "at91sam9x5ek.dtsi" / { model = "Atmel AT91SAM9G15-EK"; compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; + + ahb { + apb { + mmc1: mmc@f000c000 { + /* mmc1 pins is conflicted with spi0 pins */ + status = "disabled"; + }; + + hlcdc: hlcdc@f8038000 { + status = "okay"; + }; + }; + }; + + backlight: backlight { + status = "okay"; + }; + + bl_reg: backlight_regulator { + status = "okay"; + }; + + panel: panel { + status = "okay"; + }; + + panel_reg: panel_regulator { + status = "okay"; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g20.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g20.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g20.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:19 @ reg = <0x20000000 0x08000000>; }; + sram0: sram@002ff000 { + status = "disabled"; + }; + + sram1: sram@002fc000 { + compatible = "mmio-sram"; + reg = <0x002fc000 0x8000>; + }; + ahb { apb { i2c0: i2c@fffac000 { Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g20ek_common.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:115 @ }; }; + shdwc@fffffd10 { + atmel,wakeup-counter = <10>; + atmel,wakeup-rtt-timer; + }; + + rtc@fffffd20 { + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; + status = "okay"; + }; + watchdog@fffffd40 { status = "okay"; }; + + gpbr: syscon@fffffd50 { + status = "okay"; + }; }; nand0: nand@40000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:198 @ wm8731: wm8731@1b { compatible = "wm8731"; reg = <0x1b>; + clocks = <&pck0>; + clock-names = "mclk"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g25.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g25.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g25.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:10 @ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_isi.dtsi" #include "at91sam9x5_usart3.dtsi" #include "at91sam9x5_macb0.dtsi" Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g25ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g25ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g25ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:23 @ phy-mode = "rmii"; status = "okay"; }; + + spi0: spi@f0000000 { + status = "disabled"; + }; + + mmc1: mmc@f000c000 { + status = "disabled"; + }; + + i2c0: i2c@f8010000 { + ov2640: camera@0x30 { + status = "okay"; + }; + ov5640: camera@0x3c { + status = "okay"; + }; + ov7740: camera@0x21 { + status = "okay"; + }; + ov9740: camera@0x10 { + status = "okay"; + }; + }; + }; + + isi: isi@f8048000 { + status = "okay"; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g35.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g35.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g35.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:10 @ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_lcd.dtsi" #include "at91sam9x5_macb0.dtsi" / { Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g35ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g35ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g35ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:11 @ */ /dts-v1/; #include "at91sam9g35.dtsi" +#include "at91sam9x5dm.dtsi" #include "at91sam9x5ek.dtsi" / { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:24 @ phy-mode = "rmii"; status = "okay"; }; + + hlcdc: hlcdc@f8038000 { + status = "okay"; + }; + + mmc1: mmc@f000c000 { + /* mmc1 pins is conflicted with spi0 pins */ + status = "disabled"; + }; }; }; + + backlight: backlight { + status = "okay"; + }; + + bl_reg: backlight_regulator { + status = "okay"; + }; + + panel: panel { + status = "okay"; + }; + + panel_reg: panel_regulator { + status = "okay"; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g45.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9g45.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9g45.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:77 @ }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x10000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:446 @ >; /* shared pinctrl settings */ + ac97 { + pinctrl_ac97: ac97-0 { + atmel,pins = + <AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD6 periph A AC97_RX pin */ + AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD7 periph A AC97_TX pin */ + AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PD8 periph A AC97_FS pin */ + AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PD9 periph A AC97_CK pin */ + }; + }; + adc0 { pinctrl_adc0_adtrg: adc0_adtrg { atmel,pins = <AT91_PIOD 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:510 @ }; }; + isi { + pinctrl_isi_data_0_7: isi-0-data-0-7 { + atmel,pins = + <AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB20 periph A ISI_D0 */ + AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB21 periph A ISI_D1 */ + AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB22 periph A ISI_D2 */ + AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB23 periph A ISI_D3 */ + AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB24 periph A ISI_D4 */ + AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB25 periph A ISI_D5 */ + AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB26 periph A ISI_D6 */ + AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB27 periph A ISI_D7 */ + AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB28 periph A ISI_PCK */ + AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB29 periph A ISI_VSYNC */ + AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB30 periph A ISI_HSYNC */ + }; + + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB8 periph B ISI_D8, conflicts with TXD3 */ + AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB9 periph B ISI_D9, conflicts with RXD3 */ + }; + + pinctrl_isi_data_10_11: isi-0-data-10-11 { + atmel,pins = + <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB10 periph B ISI_D10, conflicts with TWD1 */ + AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB11 periph B ISI_D11, conflicts with TWCK1 */ + }; + }; + + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1153 @ usb2: gadget@fff78000 { #address-cells = <1>; #size-cells = <0>; - compatible = "atmel,at91sam9rl-udc"; + compatible = "atmel,at91sam9g45-udc"; reg = <0x00600000 0x80000 0xfff78000 0x400>; interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1214 @ }; }; + ac97: sound@fffac000 { + compatible = "atmel,at91sam9263-ac97c"; + reg = <0xfffac000 0x200>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ac97>; + clocks = <&ac97_clk>; + clock-names = "ac97_clk"; + status = "disabled"; + }; + sckc@fffffd50 { compatible = "atmel,at91sam9x5-sckc"; reg = <0xfffffd50 0x4>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1251 @ }; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; + rtc@fffffdb0 { compatible = "atmel,at91rm9200-rtc"; reg = <0xfffffdb0 0x30>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x10>; + status = "disabled"; + }; }; fb0: fb@0x00500000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1303 @ status = "disabled"; }; + isi: isi@fffb4000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xfffb4000 0x4000>; + interrupts = <26 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + usb0: ohci@00700000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00700000 0x100000>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; - //TODO - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1331 @ compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00800000 0x100000>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; - //TODO - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck"; + clocks = <&utmi>, <&uhphs_clk>; + clock-names = "usb_clk", "ehci_clk"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9m10g45ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9m10g45ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:65 @ i2c0: i2c@fff84000 { status = "okay"; + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioD 12 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioD 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + + ov5640: camera@0x3c { + compatible = "ovti,ov5642"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioD 12 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioD 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov5640_0: endpoint { + remote-endpoint = <&isi_1>; + bus-width = <8>; + }; + }; + }; + + ov7740: camera@0x21 { + compatible = "ovti,ov7740"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioD 12 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioD 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov7740_0: endpoint { + remote-endpoint = <&isi_2>; + bus-width = <8>; + }; + }; + }; + + ov9740: camera@0x10 { + compatible = "ovti,ov9740"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioD 12 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioD 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov9740_0: endpoint { + remote-endpoint = <&isi_3>; + bus-width = <8>; + }; + }; + }; }; i2c1: i2c@fff88000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:204 @ AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PD31 periph B */ }; }; + + camera_sensor { + pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 { + atmel,pins = + <AT91_PIOB 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB31 periph B ISI_MCK */ + }; + + pinctrl_sensor_reset: sensor_reset-0 { + atmel,pins = + <AT91_PIOD 12 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PD12 gpio */ + }; + + pinctrl_sensor_power: sensor_power-0 { + atmel,pins = + <AT91_PIOD 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PD13 gpio */ + }; + }; }; spi0: spi@fffa4000{ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:238 @ status = "okay"; }; + ac97: sound@fffac000 { + status = "okay"; + }; + adc0: adc@fffb0000 { pinctrl-names = "default"; pinctrl-0 = < @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:264 @ pinctrl-0 = <&pinctrl_pwm_leds>; }; + rtc@fffffd20 { + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; + status = "okay"; + }; + + gpbr: syscon@fffffd60 { + status = "okay"; + }; + rtc@fffffdb0 { status = "okay"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:329 @ }; }; + isi: isi@fffb4000 { + status = "okay"; + port { + isi_0: endpoint@0 { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + }; + + isi_1: endpoint@1 { + remote-endpoint = <&ov5640_0>; + bus-width = <8>; + }; + + isi_2: endpoint@2 { + remote-endpoint = <&ov7740_0>; + bus-width = <8>; + }; + + isi_3: endpoint@3 { + remote-endpoint = <&ov9740_0>; + bus-width = <8>; + }; + }; + }; + usb0: ohci@00700000 { status = "okay"; num-ports = <2>; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9n12.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9n12.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9n12.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:54 @ }; clocks { + adc_op_clk: adc_op_clk{ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + slow_xtal: slow_xtal { compatible = "fixed-clock"; #clock-cells = <0>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x8000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:452 @ clock-names = "t0_clk"; }; + hlcdc: hlcdc@f8038000 { + compatible = "atmel,at91sam9n12-hlcdc"; + reg = <0xf8038000 0x2000>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk", "sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; + dma: dma-controller@ffffec00 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:512 @ }; }; + lcd { + pinctrl_lcd_base: lcd-base-0 { + atmel,pins = + <AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */ + AT91_PIOC 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */ + AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDISP */ + AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */ + AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */ + }; + + pinctrl_lcd_pwm: lcd-pwm-0 { + atmel,pins = <AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */ + }; + + pinctrl_lcd_rgb888: lcd-rgb-3 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + }; + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:986 @ clocks = <&pwm_clk>; status = "disabled"; }; + + adc0: adc@f804c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9x5-adc"; + reg = <0xf804c000 0x100>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&adc_clk>, + <&adc_op_clk>; + clock-names = "adc_clk", "adc_op_clk"; + atmel,adc-use-external; + atmel,adc-channels-used = <0xffff>; + atmel,adc-vref = <3300>; + atmel,adc-startup-time = <40>; + atmel,adc-sample-hold-time = <11>; + atmel,adc-res = <8 10>; + atmel,adc-res-names = "lowres", "highres"; + atmel,adc-use-res = "highres"; + + trigger@0 { + reg = <0>; + trigger-name = "external-rising"; + trigger-value = <0x1>; + trigger-external; + }; + + trigger@1 { + reg = <1>; + trigger-name = "external-falling"; + trigger-value = <0x2>; + trigger-external; + }; + + trigger@2 { + reg = <2>; + trigger-name = "external-any"; + trigger-value = <0x3>; + trigger-external; + }; + + trigger@3 { + reg = <3>; + trigger-name = "continuous"; + trigger-value = <0x6>; + }; + }; + }; nand0: nand@40000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1061 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x00100000>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, - <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9n12ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9n12ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9n12ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:57 @ status = "okay"; wm8904: codec@1a { - compatible = "wm8904"; + compatible = "wlf,wm8904"; reg = <0x1a>; clocks = <&pck0>; clock-names = "mclk"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ }; }; - i2c1: i2c@f8014000 { + adc0: adc@f804c000 { + atmel,adc-ts-wires = <4>; + atmel,adc-ts-pressure-threshold = <10000>; status = "okay"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:125 @ }; }; + hlcdc: hlcdc@f8038000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + watchdog@fffffe40 { status = "okay"; }; + + rtc@fffffeb0 { + status = "okay"; + }; }; nand0: nand@40000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:167 @ }; }; + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + leds { compatible = "gpio-leds"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:194 @ }; d9 { - label = "d6"; + label = "d9"; gpios = <&pioB 5 GPIO_ACTIVE_LOW>; linux,default-trigger = "nand-disk"; }; d10 { - label = "d7"; + label = "d10"; gpios = <&pioB 6 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:217 @ }; }; + panel: panel { + compatible = "qd,qd43003c0-40", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; + sound { compatible = "atmel,asoc-wm8904"; pinctrl-names = "default"; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9rl.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9rl.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9rl.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x10000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1067 @ clocks = <&slow_rc_osc &slow_osc>; }; }; + + rtc@fffffeb0 { + compatible = "atmel,at91rm9200-rtc"; + reg = <0xfffffeb0 0x40>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + status = "disabled"; + }; + + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x10>; + status = "disabled"; + }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x25.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x25.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x25.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ #include "at91sam9x5_usart3.dtsi" #include "at91sam9x5_macb0.dtsi" #include "at91sam9x5_macb1.dtsi" +#include "at91sam9x5_can.dtsi" / { model = "Atmel AT91SAM9X25 SoC"; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x25ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x25ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x25ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:28 @ phy-mode = "rmii"; status = "okay"; }; + + spi0: spi@f0000000 { + /* mmc1 pins is conflicted with spi0 pins */ + status = "disabled"; + }; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x35.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x35.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x35.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:10 @ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_lcd.dtsi" #include "at91sam9x5_macb0.dtsi" +#include "at91sam9x5_can.dtsi" / { model = "Atmel AT91SAM9X35 SoC"; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x35ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x35ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x35ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:11 @ */ /dts-v1/; #include "at91sam9x35.dtsi" +#include "at91sam9x5dm.dtsi" #include "at91sam9x5ek.dtsi" / { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:24 @ phy-mode = "rmii"; status = "okay"; }; + + hlcdc: hlcdc@f8038000 { + status = "okay"; + }; + + spi0: spi@f0000000 { + /* mmc1 pins is conflicted with spi0 pins */ + status = "disabled"; + }; }; }; + + backlight: backlight { + status = "okay"; + }; + + bl_reg: backlight_regulator { + status = "okay"; + }; + + panel: panel { + status = "okay"; + }; + + panel_reg: panel_regulator { + status = "okay"; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_can.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5_can.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_can.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2 @ /* - * at91sam9x5_macb0.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1 + * at91sam9x5_can.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1 * Ethernet interface. * * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:23 @ reg = <29>; }; - can1_clk: can1_clk { - #clock-cells = <0>; - reg = <30>; - }; + can1_clk: can1_clk { + #clock-cells = <0>; + reg = <30>; + }; + }; + }; + + can0: can@f8000000 { + compatible = "atmel,at91sam9x5-can"; + reg = <0xf8000000 0x300>; + interrupts = <29 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_rx_tx>; + clocks = <&can0_clk>; + clock-names = "can_clk"; + status = "disabled"; + }; + + can1: can@f8004000 { + compatible = "atmel,at91sam9x5-can"; + reg = <0xf8004000 0x300>; + interrupts = <30 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_rx_tx>; + clocks = <&can1_clk>; + clock-names = "can_clk"; + status = "disabled"; + }; + + pinctrl@fffff400 { + can0 { + pinctrl_can0_rx_tx: can0_rx_tx { + atmel,pins = + <AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* CANRX0, conflicts with DRXD */ + AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* CANTX0, conflicts with DTXD */ + }; + }; + + can1 { + pinctrl_can1_rx_tx: can1_rx_tx { + atmel,pins = + <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE /* CANRX1, conflicts with RXD1 */ + AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* CANTX1, conflicts with TXD1 */ + }; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5cm.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5cm.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5cm.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:45 @ }; }; }; + + rtc@fffffeb0 { + status = "okay"; + }; }; nand0: nand@40000000 { Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5dm.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5dm.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * at91sam9x5dm.dtsi - Device Tree file for SAM9x5 display module + * + * Copyright (C) 2014 Atmel, + * 2014 Free Electrons + * + * Author: Boris Brezillon <boris.brezillon@free-electrons.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c0: i2c@f8010000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioA>; + interrupts = <7 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + }; + + hlcdc: hlcdc@f8038000 { + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + pinctrl@fffff400 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "disabled"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "disabled"; + }; + + panel: panel { + compatible = "foxlink,fl500wvr00-a0t", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "disabled"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:71 @ adc_op_clk: adc_op_clk{ compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <5000000>; + clock-frequency = <1000000>; }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x8000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:508 @ pinctrl_usart1_sck: usart1_sck-0 { atmel,pins = - <AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC29 periph C */ + <AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC29 periph C */ }; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:868 @ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; + dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(8)>, + <&dma1 1 (AT91_DMA_CFG_PER_ID(9) | AT91_DMA_CFG_FIFOCFG_ASAP)>; + dma-names = "tx", "rx"; clocks = <&mck>; clock-names = "usart"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:882 @ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart0>; + dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(3)>, + <&dma0 1 (AT91_DMA_CFG_PER_ID(4) | AT91_DMA_CFG_FIFOCFG_ASAP)>; + dma-names = "tx", "rx"; clocks = <&usart0_clk>; clock-names = "usart"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:896 @ interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart1>; + dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(5)>, + <&dma0 1 (AT91_DMA_CFG_PER_ID(6) | AT91_DMA_CFG_FIFOCFG_ASAP)>; + dma-names = "tx", "rx"; clocks = <&usart1_clk>; clock-names = "usart"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:910 @ interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart2>; + dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(12)>, + <&dma1 1 (AT91_DMA_CFG_PER_ID(13) | AT91_DMA_CFG_FIFOCFG_ASAP)>; + dma-names = "tx", "rx"; clocks = <&usart2_clk>; clock-names = "usart"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:998 @ atmel,adc-channels-used = <0xffff>; atmel,adc-vref = <3300>; atmel,adc-startup-time = <40>; + atmel,adc-sample-hold-time = <11>; atmel,adc-res = <8 10>; atmel,adc-res-names = "lowres", "highres"; atmel,adc-use-res = "highres"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1066 @ usb2: gadget@f803c000 { #address-cells = <1>; #size-cells = <0>; - compatible = "atmel,at91sam9rl-udc"; + compatible = "atmel,at91sam9g45-udc"; reg = <0x00500000 0x80000 0xf803c000 0x400>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; - clocks = <&usb>, <&udphs_clk>; + clocks = <&utmi>, <&udphs_clk>; clock-names = "hclk", "pclk"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1181 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1190 @ compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00700000 0x100000>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ehci_clk", "uhpck"; + clocks = <&utmi>, <&uhphs_clk>; + clock-names = "usb_clk", "ehci_clk"; status = "disabled"; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5ek.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5ek.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:19 @ bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; }; + clocks { + wm8731_xtal: wm8731_xtal { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12288000>; + }; + }; + ahb { apb { mmc0: mmc@f0008000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:74 @ wm8731: wm8731@1a { compatible = "wm8731"; reg = <0x1a>; + clocks = <&wm8731_xtal>; + clock-names = "mclk"; + }; + + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck0>; + clock-names = "xvclk"; + assigned-clocks = <&pck0>; + assigned-clock-rates = <25000000>; + + status = "disabled"; + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + + ov5640: camera@0x3c { + compatible = "ovti,ov5642"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck0>; + clock-names = "xvclk"; + assigned-clocks = <&pck0>; + assigned-clock-rates = <25000000>; + + status = "disabled"; + port { + ov5640_0: endpoint { + remote-endpoint = <&isi_1>; + bus-width = <8>; + }; + }; + }; + + ov7740: camera@0x21 { + compatible = "ovti,ov7740"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck0>; + clock-names = "xvclk"; + assigned-clocks = <&pck0>; + assigned-clock-rates = <25000000>; + + status = "disabled"; + port { + ov7740_0: endpoint { + remote-endpoint = <&isi_2>; + bus-width = <8>; + }; + }; + }; + + ov9740: camera@0x10 { + compatible = "ovti,ov9740"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck0>; + clock-names = "xvclk"; + assigned-clocks = <&pck0>; + assigned-clock-rates = <25000000>; + + status = "disabled"; + port { + ov9740_0: endpoint { + remote-endpoint = <&isi_3>; + bus-width = <8>; + }; + }; }; }; + adc0: adc@f804c000 { + atmel,adc-ts-wires = <4>; + atmel,adc-ts-pressure-threshold = <10000>; + status = "okay"; + }; + pinctrl@fffff400 { mmc0 { pinctrl_board_mmc0: mmc0-board { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:183 @ <AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD14 gpio CD pin pull up and deglitch */ }; }; + + camera_sensor { + pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 { + atmel,pins = + <AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC15 periph C ISI_MCK */ + }; + + pinctrl_sensor_reset: sensor_reset-0 { + atmel,pins = + <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PA7 gpio */ + }; + + pinctrl_sensor_power: sensor_power-0 { + atmel,pins = + <AT91_PIOA 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PA13 gpio */ + }; + }; }; spi0: spi@f0000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:221 @ }; }; + isi: isi@f8048000 { + status = "disabled"; + port { + isi_0: endpoint@0 { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + }; + + isi_1: endpoint@1 { + remote-endpoint = <&ov5640_0>; + bus-width = <8>; + }; + + isi_2: endpoint@2 { + remote-endpoint = <&ov7740_0>; + bus-width = <8>; + }; + + isi_3: endpoint@3 { + remote-endpoint = <&ov9740_0>; + bus-width = <8>; + }; + }; + }; + usb0: ohci@00600000 { status = "okay"; num-ports = <3>; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_isi.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5_isi.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_isi.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:24 @ }; }; }; + + pinctrl@fffff400 { + isi { + pinctrl_isi_data_0_7: isi-0-data-0-7 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC0 periph B ISI_D0, conflicts with LCDDAT0 */ + AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC1 periph B ISI_D1, conflicts with LCDDAT1 */ + AT91_PIOC 2 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC2 periph B ISI_D2, conflicts with LCDDAT2 */ + AT91_PIOC 3 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC3 periph B ISI_D3, conflicts with LCDDAT3 */ + AT91_PIOC 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC4 periph B ISI_D4, conflicts with LCDDAT4 */ + AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC5 periph B ISI_D5, conflicts with LCDDAT5 */ + AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC6 periph B ISI_D6, conflicts with LCDDAT6 */ + AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC7 periph B ISI_D7, conflicts with LCDDAT7 */ + AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC12 periph B ISI_PCK, conflicts with LCDDAT12 */ + AT91_PIOC 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC14 periph B ISI_HSYNC, conflicts with LCDDAT14 */ + AT91_PIOC 13 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC13 periph B ISI_VSYNC, conflicts with LCDDAT13 */ + }; + + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC8 periph B ISI_D8, conflicts with LCDDAT8 */ + AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC9 periph B ISI_D9, conflicts with LCDDAT9 */ + }; + + pinctrl_isi_data_10_11: isi-0-data-10-11 { + atmel,pins = + <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC10 periph B ISI_D10, conflicts with LCDDAT10 */ + AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC11 periph B ISI_D11, conflicts with LCDDAT11 */ + }; + }; + }; + }; + + isi: isi@f8048000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xf8048000 0x4000>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_lcd.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5_lcd.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_lcd.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:16 @ / { ahb { apb { + hlcdc: hlcdc@f8038000 { + compatible = "atmel,at91sam9x5-hlcdc"; + reg = <0xf8038000 0x4000>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; + + pinctrl@fffff400 { + lcd { + pinctrl_lcd_base: lcd-base-0 { + atmel,pins = + <AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */ + AT91_PIOC 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */ + AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDISP */ + AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */ + AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */ + }; + + pinctrl_lcd_pwm: lcd-pwm-0 { + atmel,pins = <AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */ + }; + + pinctrl_lcd_rgb444: lcd-rgb-0 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */ + }; + + pinctrl_lcd_rgb565: lcd-rgb-1 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */ + }; + + pinctrl_lcd_rgb666: lcd-rgb-2 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD17 pin */ + }; + + pinctrl_lcd_rgb888: lcd-rgb-3 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + }; + }; + pmc: pmc@fffffc00 { periphck { lcdc_clk: lcdc_clk { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:154 @ reg = <25>; }; }; + + systemck { + lcdck: lcdck { + #clock-cells = <0>; + reg = <3>; + clocks = <&mck>; + }; + }; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_usart3.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91sam9x5_usart3.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91sam9x5_usart3.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart3>; + dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(14)>, + <&dma1 1 (AT91_DMA_CFG_PER_ID(15) | AT91_DMA_CFG_FIFOCFG_ASAP)>; + dma-names = "tx", "rx"; clocks = <&usart3_clk>; clock-names = "usart"; status = "disabled"; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_dm_pda4.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_dm_pda4.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree Include file for PDA4 display module on SAMA5D3 Xplained board + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <8 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + atmel_mxt_ts@4a { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4a>; + interrupt-parent = <&pioE>; + interrupts = <7 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; + }; + + hlcdc: hlcdc@f0030000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888_alt>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + pinctrl@fffff200 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "innolux,at043tn24", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_dm_pda7.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_dm_pda7.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree Include file for PDA7 display module on SAMA5D3 Xplained board + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <8 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + atmel_mxt_ts@4c { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4c>; + interrupt-parent = <&pioE>; + interrupts = <7 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; + }; + + hlcdc: hlcdc@f0030000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb666_alt>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + pinctrl@fffff200 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "shelly,sca07010-bfn-lnn", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ #include "sama5d36.dtsi" / { - model = "SAMA5D3 Xplained"; + model = "Atmel SAMA5D3 Xplained"; compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5"; chosen { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:66 @ pmic: act8865@5b { compatible = "active-semi,act8865"; reg = <0x5b>; - status = "okay"; + status = "disabled"; regulators { vcc_1v8_reg: DCDC_REG1 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:205 @ atmel,pins = <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ }; + + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; }; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:284 @ gpio_keys { compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + bp3 { label = "PB_USER"; gpios = <&pioE 29 GPIO_ACTIVE_LOW>; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for the SAMA5D3 Xplained board with PDA4.3 screen + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "at91-sama5d3_xplained_dm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D3 Xplained TM43xx"; + compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x10000000>; + }; + + clocks { + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + mmc0: mmc@f0000000 { + pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <8>; + cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>; + }; + }; + + spi0: spi@f0004000 { + cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>; + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + pinctrl-0 = <&pinctrl_i2c0_pu>; + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + phy-mode = "rgmii"; + status = "okay"; + }; + + pwm0: pwm@f002c000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_pwmh0_0 &pinctrl_pwm0_pwmh1_0>; + status = "okay"; + }; + + usart0: serial@f001c000 { + status = "okay"; + }; + + usart1: serial@f0020000 { + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>; + status = "okay"; + }; + + uart0: serial@f0024000 { + status = "okay"; + }; + + mmc1: mmc@f8000000 { + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>; + }; + }; + + spi1: spi@f8008000 { + cs-gpios = <&pioC 25 0>; + status = "okay"; + }; + + adc0: adc@f8018000 { + pinctrl-0 = < + &pinctrl_adc0_adtrg + &pinctrl_adc0_ad0 + &pinctrl_adc0_ad1 + &pinctrl_adc0_ad2 + &pinctrl_adc0_ad3 + &pinctrl_adc0_ad4 + &pinctrl_adc0_ad5 + &pinctrl_adc0_ad6 + &pinctrl_adc0_ad7 + &pinctrl_adc0_ad8 + &pinctrl_adc0_ad9 + >; + status = "okay"; + }; + + i2c2: i2c@f801c000 { + dmas = <0>, <0>; /* Do not use DMA for i2c2 */ + pinctrl-0 = <&pinctrl_i2c2_pu>; + status = "okay"; + }; + + macb1: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + dbgu: serial@ffffee00 { + status = "okay"; + }; + + pinctrl@fffff200 { + board { + pinctrl_i2c0_pu: i2c0_pu { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>, + <AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; + }; + + pinctrl_i2c2_pu: i2c2_pu { + atmel,pins = + <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>, + <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; + }; + + pinctrl_mmc0_cd: mmc0_cd { + atmel,pins = + <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ + }; + + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + + pmc: pmc@fffffc00 { + main: mainck { + clock-frequency = <12000000>; + }; + }; + }; + + nand0: nand@60000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + atmel,has-pmecc; + atmel,pmecc-cap = <4>; + atmel,pmecc-sector-size = <512>; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + + usb0: gadget@00500000 { + atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00600000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 3 GPIO_ACTIVE_LOW + &pioE 4 GPIO_ACTIVE_LOW + >; + status = "okay"; + }; + + usb2: ehci@00700000 { + status = "okay"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + bp3 { + label = "PB_USER"; + gpios = <&pioE 29 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + + d2 { + label = "d2"; + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */ + linux,default-trigger = "heartbeat"; + }; + + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d3_xplained_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for the SAMA5D3 Xplained board with PDA7 screen + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "at91-sama5d3_xplained_dm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D3 Xplained TM70xx"; + compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x10000000>; + }; + + clocks { + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + mmc0: mmc@f0000000 { + pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <8>; + cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>; + }; + }; + + spi0: spi@f0004000 { + cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>; + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + pinctrl-0 = <&pinctrl_i2c0_pu>; + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + phy-mode = "rgmii"; + status = "okay"; + }; + + pwm0: pwm@f002c000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_pwmh0_0 &pinctrl_pwm0_pwmh1_0>; + status = "okay"; + }; + + usart0: serial@f001c000 { + status = "okay"; + }; + + usart1: serial@f0020000 { + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>; + status = "okay"; + }; + + uart0: serial@f0024000 { + status = "okay"; + }; + + mmc1: mmc@f8000000 { + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>; + }; + }; + + spi1: spi@f8008000 { + cs-gpios = <&pioC 25 0>; + status = "okay"; + }; + + adc0: adc@f8018000 { + pinctrl-0 = < + &pinctrl_adc0_adtrg + &pinctrl_adc0_ad0 + &pinctrl_adc0_ad1 + &pinctrl_adc0_ad2 + &pinctrl_adc0_ad3 + &pinctrl_adc0_ad4 + &pinctrl_adc0_ad5 + &pinctrl_adc0_ad6 + &pinctrl_adc0_ad7 + &pinctrl_adc0_ad8 + &pinctrl_adc0_ad9 + >; + status = "okay"; + }; + + i2c2: i2c@f801c000 { + dmas = <0>, <0>; /* Do not use DMA for i2c2 */ + pinctrl-0 = <&pinctrl_i2c2_pu>; + status = "okay"; + }; + + macb1: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + dbgu: serial@ffffee00 { + status = "okay"; + }; + + pinctrl@fffff200 { + board { + pinctrl_i2c0_pu: i2c0_pu { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>, + <AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; + }; + + pinctrl_i2c2_pu: i2c2_pu { + atmel,pins = + <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>, + <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; + }; + + pinctrl_mmc0_cd: mmc0_cd { + atmel,pins = + <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ + }; + + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + + pmc: pmc@fffffc00 { + main: mainck { + clock-frequency = <12000000>; + }; + }; + }; + + nand0: nand@60000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + atmel,has-pmecc; + atmel,pmecc-cap = <4>; + atmel,pmecc-sector-size = <512>; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + + usb0: gadget@00500000 { + atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00600000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 3 GPIO_ACTIVE_LOW + &pioE 4 GPIO_ACTIVE_LOW + >; + status = "okay"; + }; + + usb2: ehci@00700000 { + status = "okay"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + bp3 { + label = "PB_USER"; + gpios = <&pioE 29 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + + d2 { + label = "d2"; + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */ + linux,default-trigger = "heartbeat"; + }; + + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/at91-sama5d4ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3 @ /* * at91-sama5d4ek.dts - Device Tree file for SAMA5D4 Evaluation Kit + * EK with PDA TM70xx 7" LCD + touchscreen display * * Copyright (C) 2014 Atmel, * 2014 Nicolas Ferre <nicolas.ferre@atmel.com> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * licensing only applies to this file, and not this project as a * whole. * - * a) This library is free software; you can redistribute it and/or + * a) This file 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 library is distributed in the hope that it will be useful, + * This file 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. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:82 @ ahb { apb { - lcd_bus@f0000000 { + hlcdc: hlcdc@f0000000 { status = "okay"; - lcd@f0000000 { - status = "okay"; - }; - - lcdovl1@f0000140 { - status = "okay"; - }; - - lcdovl2@f0000240 { - status = "okay"; - }; - - lcdheo1@f0000340 { - status = "okay"; + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb666>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + + hlcdc_hdmi_output: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_input>; + }; + }; }; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:120 @ }; }; + ssc0: ssc@f8008000 { + status = "okay"; + }; + spi0: spi@f8010000 { cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; status = "okay"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:136 @ i2c0: i2c@f8014000 { status = "okay"; + + wm8904: codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&pck2>; + clock-names = "mclk"; + }; + + qt1070:keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <25 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioB 11 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioB 5 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + + sil9022: hdmi-encoder@39 { + compatible = "sil,sil9022"; + reg = <0x39>; + reset-gpios = <&pioB 15 GPIO_ACTIVE_LOW>; + interrupts-extended = <&pioE 3 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sil9022_irq>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_hdmi_output>; + }; + }; + }; + + ov5640: camera@0x3c { + compatible = "ovti,ov5642"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioB 11 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioB 5 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov5640_0: endpoint { + remote-endpoint = <&isi_1>; + bus-width = <8>; + }; + }; + }; + + ov7740: camera@0x21 { + compatible = "ovti,ov7740"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioB 11 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioB 5 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov7740_0: endpoint { + remote-endpoint = <&isi_2>; + bus-width = <8>; + }; + }; + }; + + ov9740: camera@0x10 { + compatible = "ovti,ov9740"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioB 11 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioB 5 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov9740_0: endpoint { + remote-endpoint = <&isi_3>; + bus-width = <8>; + }; + }; + }; + + atmel_mxt_ts@4c { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4c>; + interrupt-parent = <&pioE>; + interrupts = <24 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; }; macb0: ethernet@f8020000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:279 @ }; }; - usart2: serial@fc008000 { - status = "okay"; - }; - usart3: serial@fc00c000 { status = "okay"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:301 @ atmel,pins = <AT91_PIOE 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; }; + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; pinctrl_usba_vbus: usba_vbus { atmel,pins = <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:313 @ atmel,pins = <AT91_PIOE 13 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE13 gpio */ }; + pinctrl_pck2_as_audio_mck: pck2_as_audio_mck { + atmel,pins = + <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; + }; + pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 { + atmel,pins = + <AT91_PIOC 4 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC4 periph C PCK1, conflicted with SPI0_NPCS1, MCI0_CK */ + }; + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 25 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + pinctrl_sensor_reset: sensor_reset-0 { + atmel,pins = + <AT91_PIOB 11 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PB11 gpio */ + }; + pinctrl_sensor_power: sensor_power-0 { + atmel,pins = + <AT91_PIOB 5 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PB5 gpio */ + }; + pinctrl_sil9022_irq: sil9022_irq-0 { + atmel,pins = + <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; }; }; }; + vdec0: vdec@00300000 { + status = "okay"; + }; + usb0: gadget@00400000 { atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:402 @ reg = <0x800000 0x0f800000>; }; }; + + isi: isi@f0008000 { + status = "okay"; + port { + isi_0: endpoint@0 { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + }; + + isi_1: endpoint@1 { + remote-endpoint = <&ov5640_0>; + bus-width = <8>; + }; + + isi_2: endpoint@2 { + remote-endpoint = <&ov7740_0>; + bus-width = <8>; + }; + + isi_3: endpoint@3 { + remote-endpoint = <&ov9740_0>; + bus-width = <8>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; }; gpio_keys { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:461 @ gpio-key,wakeup; }; }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + /* PE28, conflicts with usart4 rts pin */ + gpios = <&pioE 28 GPIO_ACTIVE_LOW>; + }; + + d9 { + label = "d9"; + gpios = <&pioE 9 GPIO_ACTIVE_HIGH>; + }; + + d10 { + label = "d10"; + gpios = <&pioE 8 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; + + panel: panel { + compatible = "shelly,sca07010-bfn-lnn", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; + + sound { + compatible = "atmel,asoc-wm8904"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck2_as_audio_mck>; + + atmel,model = "wm8904 @ SAMA5D4EK"; + atmel,audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN1L", "Line In Jack", + "IN1R", "Line In Jack"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8904>; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_dm_pda4.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_dm_pda4.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree Include file for PDA4 display module on SAMA5D4 Xplained board + * + * Copyright (C) 2014 Atmel, + * 2014 Josh Wu <josh.wu@atmel.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/ { + ahb { + apb { + i2c0: i2c@f8014000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <10 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + atmel_mxt_ts@4a { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4a>; + interrupt-parent = <&pioE>; + interrupts = <9 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; + }; + + hlcdc: hlcdc@f0000000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb777>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + pinctrl@fc06a000 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 10 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "innolux,at043tn24", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * at91-sama5d4_xplained.dts - Device Tree file for SAMA5D4 Xplained board + * + * Copyright (C) 2015 Atmel, + * 2015 Josh Wu <josh.wu@atmel.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "sama5d4.dtsi" + +/ { + model = "Atmel SAMA5D4 Xplained"; + compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x20000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + spi0: spi@f8010000 { + cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; + status = "okay"; + m25p80@0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <50000000>; + reg = <0>; + }; + }; + + i2c0: i2c@f8014000 { + status = "okay"; + }; + + macb0: ethernet@f8020000 { + phy-mode = "rmii"; + status = "okay"; + + phy0: ethernet-phy@1 { + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + reg = <1>; + }; + }; + + mmc1: mmc@fc000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 3 0>; + }; + }; + + usart3: serial@fc00c000 { + status = "okay"; + }; + + usart4: serial@fc010000 { + status = "okay"; + }; + + spi1: spi@fc018000 { + cs-gpios = <&pioB 21 0>; + status = "okay"; + }; + + adc0: adc@fc034000 { + atmel,adc-vref = <3300>; + status = "okay"; + }; + + watchdog@fc068640 { + status = "okay"; + }; + + pinctrl@fc06a000 { + board { + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; + }; + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + + usb0: gadget@00400000 { + atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00500000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 11 GPIO_ACTIVE_HIGH + &pioE 14 GPIO_ACTIVE_HIGH + >; + status = "okay"; + }; + + usb2: ehci@00600000 { + status = "okay"; + }; + + nand0: nand@80000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + atmel,has-pmecc; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + pb_user1 { + label = "pb_user1"; + gpios = <&pioE 8 GPIO_ACTIVE_HIGH>; + linux,code = <0x100>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + d10 { + label = "d10"; + gpios = <&pioE 15 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_hdmi.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_hdmi.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for the SAMA5D4 Xplained board with HDMI + * + * Copyright (C) 2014 Atmel, + * 2014 Josh Wu <josh.wu@atmel.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "sama5d4.dtsi" + +/ { + model = "Atmel SAMA5D4 Xplained Sil9022"; + compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x20000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + hlcdc: hlcdc@f0000000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb777>; + + port@0 { + hlcdc_hdmi_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&hdmi_input>; + }; + }; + }; + }; + + spi0: spi@f8010000 { + cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; + status = "okay"; + m25p80@0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <50000000>; + reg = <0>; + }; + }; + + i2c0: i2c@f8014000 { + status = "okay"; + + sil9022: hdmi-encoder@39 { + compatible = "sil,sil9022"; + reg = <0x39>; + reset-gpios = <&pioB 15 GPIO_ACTIVE_LOW>; + interrupts-extended = <&pioA 25 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sil9022_irq>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_hdmi_output>; + }; + }; + }; + + }; + + macb0: ethernet@f8020000 { + phy-mode = "rmii"; + status = "okay"; + + phy0: ethernet-phy@1 { + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + reg = <1>; + }; + }; + + mmc1: mmc@fc000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 3 0>; + }; + }; + + usart3: serial@fc00c000 { + status = "okay"; + }; + + usart4: serial@fc010000 { + status = "okay"; + }; + + adc0: adc@fc034000 { + atmel,adc-vref = <3300>; + status = "okay"; + }; + + watchdog@fc068640 { + status = "okay"; + }; + + pinctrl@fc06a000 { + board { + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; + }; + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + pinctrl_sil9022_irq: sil9022_irq-0 { + atmel,pins = + <AT91_PIOA 25 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + + vdec0: vdec@00300000 { + status = "okay"; + }; + + usb0: gadget@00400000 { + atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00500000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 11 GPIO_ACTIVE_HIGH + &pioE 14 GPIO_ACTIVE_HIGH + >; + status = "okay"; + }; + + usb2: ehci@00600000 { + status = "okay"; + }; + + nand0: nand@80000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + atmel,has-pmecc; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + pb_user1 { + label = "pb_user1"; + gpios = <&pioE 8 GPIO_ACTIVE_HIGH>; + linux,code = <0x100>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + d10 { + label = "d10"; + gpios = <&pioE 15 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91-sama5d4_xplained_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for the SAMA5D4 Xplained board with PDA4 screen + * + * Copyright (C) 2014 Atmel, + * 2014 Josh Wu <josh.wu@atmel.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "sama5d4.dtsi" +#include "at91-sama5d4_xplained_dm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D4 Xplained TM43xx"; + compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x20000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + spi0: spi@f8010000 { + cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; + status = "okay"; + m25p80@0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <50000000>; + reg = <0>; + }; + }; + + i2c0: i2c@f8014000 { + status = "okay"; + }; + + macb0: ethernet@f8020000 { + phy-mode = "rmii"; + status = "okay"; + + phy0: ethernet-phy@1 { + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + reg = <1>; + }; + }; + + mmc1: mmc@fc000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 3 0>; + }; + }; + + usart3: serial@fc00c000 { + status = "okay"; + }; + + usart4: serial@fc010000 { + status = "okay"; + }; + + adc0: adc@fc034000 { + atmel,adc-vref = <3300>; + status = "okay"; + }; + + watchdog@fc068640 { + status = "okay"; + }; + + pinctrl@fc06a000 { + board { + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; + }; + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + + vdec0: vdec@00300000 { + status = "okay"; + }; + + usb0: gadget@00400000 { + atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00500000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 11 GPIO_ACTIVE_HIGH + &pioE 14 GPIO_ACTIVE_HIGH + >; + status = "okay"; + }; + + usb2: ehci@00600000 { + status = "okay"; + }; + + nand0: nand@80000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + atmel,has-pmecc; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + pb_user1 { + label = "pb_user1"; + gpios = <&pioE 8 GPIO_ACTIVE_HIGH>; + linux,code = <0x100>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + d10 { + label = "d10"; + gpios = <&pioE 15 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/include/dt-bindings/dma/at91.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/include/dt-bindings/dma/at91.h +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/include/dt-bindings/dma/at91.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ #ifndef __DT_BINDINGS_AT91_DMA_H__ #define __DT_BINDINGS_AT91_DMA_H__ +/* ---------- HDMAC ---------- */ + +/* ---------- HDMAC ---------- */ + +/* ---------- HDMAC ---------- */ + +/* ---------- HDMAC ---------- */ + +/* ---------- HDMAC ---------- */ + /* * Source and/or destination peripheral ID */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:37 @ #define AT91_DMA_CFG_FIFOCFG_ALAP (0x1 << AT91_DMA_CFG_FIFOCFG_OFFSET) /* largest defined AHB burst */ #define AT91_DMA_CFG_FIFOCFG_ASAP (0x2 << AT91_DMA_CFG_FIFOCFG_OFFSET) /* single AHB access */ + +/* ---------- XDMAC ---------- */ +#define AT91_XDMAC_DT_MEM_IF_MASK (0x1) +#define AT91_XDMAC_DT_MEM_IF_OFFSET (13) +#define AT91_XDMAC_DT_MEM_IF(mem_if) (((mem_if) & AT91_XDMAC_DT_MEM_IF_MASK) \ + << AT91_XDMAC_DT_MEM_IF_OFFSET) +#define AT91_XDMAC_DT_GET_MEM_IF(cfg) (((cfg) >> AT91_XDMAC_DT_MEM_IF_OFFSET) \ + & AT91_XDMAC_DT_MEM_IF_MASK) + +#define AT91_XDMAC_DT_PER_IF_MASK (0x1) +#define AT91_XDMAC_DT_PER_IF_OFFSET (14) +#define AT91_XDMAC_DT_PER_IF(per_if) (((per_if) & AT91_XDMAC_DT_PER_IF_MASK) \ + << AT91_XDMAC_DT_PER_IF_OFFSET) +#define AT91_XDMAC_DT_GET_PER_IF(cfg) (((cfg) >> AT91_XDMAC_DT_PER_IF_OFFSET) \ + & AT91_XDMAC_DT_PER_IF_MASK) + +#define AT91_XDMAC_DT_PERID_MASK (0x7f) +#define AT91_XDMAC_DT_PERID_OFFSET (24) +#define AT91_XDMAC_DT_PERID(perid) (((perid) & AT91_XDMAC_DT_PERID_MASK) \ + << AT91_XDMAC_DT_PERID_OFFSET) +#define AT91_XDMAC_DT_GET_PERID(cfg) (((cfg) >> AT91_XDMAC_DT_PERID_OFFSET) \ + & AT91_XDMAC_DT_PERID_MASK) + + +/* ---------- XDMAC ---------- */ +#define AT91_XDMAC_DT_MEM_IF_MASK (0x1) +#define AT91_XDMAC_DT_MEM_IF_OFFSET (13) +#define AT91_XDMAC_DT_MEM_IF(mem_if) (((mem_if) & AT91_XDMAC_DT_MEM_IF_MASK) \ + << AT91_XDMAC_DT_MEM_IF_OFFSET) +#define AT91_XDMAC_DT_GET_MEM_IF(cfg) (((cfg) >> AT91_XDMAC_DT_MEM_IF_OFFSET) \ + & AT91_XDMAC_DT_MEM_IF_MASK) + +#define AT91_XDMAC_DT_PER_IF_MASK (0x1) +#define AT91_XDMAC_DT_PER_IF_OFFSET (14) +#define AT91_XDMAC_DT_PER_IF(per_if) (((per_if) & AT91_XDMAC_DT_PER_IF_MASK) \ + << AT91_XDMAC_DT_PER_IF_OFFSET) +#define AT91_XDMAC_DT_GET_PER_IF(cfg) (((cfg) >> AT91_XDMAC_DT_PER_IF_OFFSET) \ + & AT91_XDMAC_DT_PER_IF_MASK) + +#define AT91_XDMAC_DT_PERID_MASK (0x7f) +#define AT91_XDMAC_DT_PERID_OFFSET (24) +#define AT91_XDMAC_DT_PERID(perid) (((perid) & AT91_XDMAC_DT_PERID_MASK) \ + << AT91_XDMAC_DT_PERID_OFFSET) +#define AT91_XDMAC_DT_GET_PERID(cfg) (((cfg) >> AT91_XDMAC_DT_PERID_OFFSET) \ + & AT91_XDMAC_DT_PERID_MASK) + + +/* ---------- XDMAC ---------- */ +#define AT91_XDMAC_DT_MEM_IF_MASK (0x1) +#define AT91_XDMAC_DT_MEM_IF_OFFSET (13) +#define AT91_XDMAC_DT_MEM_IF(mem_if) (((mem_if) & AT91_XDMAC_DT_MEM_IF_MASK) \ + << AT91_XDMAC_DT_MEM_IF_OFFSET) +#define AT91_XDMAC_DT_GET_MEM_IF(cfg) (((cfg) >> AT91_XDMAC_DT_MEM_IF_OFFSET) \ + & AT91_XDMAC_DT_MEM_IF_MASK) + +#define AT91_XDMAC_DT_PER_IF_MASK (0x1) +#define AT91_XDMAC_DT_PER_IF_OFFSET (14) +#define AT91_XDMAC_DT_PER_IF(per_if) (((per_if) & AT91_XDMAC_DT_PER_IF_MASK) \ + << AT91_XDMAC_DT_PER_IF_OFFSET) +#define AT91_XDMAC_DT_GET_PER_IF(cfg) (((cfg) >> AT91_XDMAC_DT_PER_IF_OFFSET) \ + & AT91_XDMAC_DT_PER_IF_MASK) + +#define AT91_XDMAC_DT_PERID_MASK (0x7f) +#define AT91_XDMAC_DT_PERID_OFFSET (24) +#define AT91_XDMAC_DT_PERID(perid) (((perid) & AT91_XDMAC_DT_PERID_MASK) \ + << AT91_XDMAC_DT_PERID_OFFSET) +#define AT91_XDMAC_DT_GET_PERID(cfg) (((cfg) >> AT91_XDMAC_DT_PERID_OFFSET) \ + & AT91_XDMAC_DT_PERID_MASK) + + +/* ---------- XDMAC ---------- */ +#define AT91_XDMAC_DT_MEM_IF_MASK (0x1) +#define AT91_XDMAC_DT_MEM_IF_OFFSET (13) +#define AT91_XDMAC_DT_MEM_IF(mem_if) (((mem_if) & AT91_XDMAC_DT_MEM_IF_MASK) \ + << AT91_XDMAC_DT_MEM_IF_OFFSET) +#define AT91_XDMAC_DT_GET_MEM_IF(cfg) (((cfg) >> AT91_XDMAC_DT_MEM_IF_OFFSET) \ + & AT91_XDMAC_DT_MEM_IF_MASK) + +#define AT91_XDMAC_DT_PER_IF_MASK (0x1) +#define AT91_XDMAC_DT_PER_IF_OFFSET (14) +#define AT91_XDMAC_DT_PER_IF(per_if) (((per_if) & AT91_XDMAC_DT_PER_IF_MASK) \ + << AT91_XDMAC_DT_PER_IF_OFFSET) +#define AT91_XDMAC_DT_GET_PER_IF(cfg) (((cfg) >> AT91_XDMAC_DT_PER_IF_OFFSET) \ + & AT91_XDMAC_DT_PER_IF_MASK) + +#define AT91_XDMAC_DT_PERID_MASK (0x7f) +#define AT91_XDMAC_DT_PERID_OFFSET (24) +#define AT91_XDMAC_DT_PERID(perid) (((perid) & AT91_XDMAC_DT_PERID_MASK) \ + << AT91_XDMAC_DT_PERID_OFFSET) +#define AT91_XDMAC_DT_GET_PERID(cfg) (((cfg) >> AT91_XDMAC_DT_PERID_OFFSET) \ + & AT91_XDMAC_DT_PERID_MASK) + + +/* ---------- XDMAC ---------- */ +#define AT91_XDMAC_DT_MEM_IF_MASK (0x1) +#define AT91_XDMAC_DT_MEM_IF_OFFSET (13) +#define AT91_XDMAC_DT_MEM_IF(mem_if) (((mem_if) & AT91_XDMAC_DT_MEM_IF_MASK) \ + << AT91_XDMAC_DT_MEM_IF_OFFSET) +#define AT91_XDMAC_DT_GET_MEM_IF(cfg) (((cfg) >> AT91_XDMAC_DT_MEM_IF_OFFSET) \ + & AT91_XDMAC_DT_MEM_IF_MASK) + +#define AT91_XDMAC_DT_PER_IF_MASK (0x1) +#define AT91_XDMAC_DT_PER_IF_OFFSET (14) +#define AT91_XDMAC_DT_PER_IF(per_if) (((per_if) & AT91_XDMAC_DT_PER_IF_MASK) \ + << AT91_XDMAC_DT_PER_IF_OFFSET) +#define AT91_XDMAC_DT_GET_PER_IF(cfg) (((cfg) >> AT91_XDMAC_DT_PER_IF_OFFSET) \ + & AT91_XDMAC_DT_PER_IF_MASK) + +#define AT91_XDMAC_DT_PERID_MASK (0x7f) +#define AT91_XDMAC_DT_PERID_OFFSET (24) +#define AT91_XDMAC_DT_PERID(perid) (((perid) & AT91_XDMAC_DT_PERID_MASK) \ + << AT91_XDMAC_DT_PERID_OFFSET) +#define AT91_XDMAC_DT_GET_PERID(cfg) (((cfg) >> AT91_XDMAC_DT_PERID_OFFSET) \ + & AT91_XDMAC_DT_PERID_MASK) + #endif /* __DT_BINDINGS_AT91_DMA_H__ */ Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/Makefile +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:46 @ dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb # sama5d3 dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained_pda7.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d31ek_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d31ek_pda7.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d31ek_revc.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d31ek_revc_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d31ek_revc_pda7.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d33ek_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d33ek_pda7.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d33ek_revc.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d33ek_revc_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d33ek_revc_pda7.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d34ek_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d34ek_pda7.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d34ek_revc.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d34ek_revc_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d34ek_revc_pda7.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d35ek_revc.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek_pda7.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek_revc.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek_revc_pda4.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek_revc_pda7.dtb # sama5d4 +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4_xplained.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4_xplained_hdmi.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4_xplained_pda4.dtb dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4ek.dtb dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d31ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ /dts-v1/; #include "sama5d31.dtsi" #include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ #include "sama5d3xdm.dtsi" / { Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d31ek_pda4.dts - Device Tree file for SAMA5D31-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d31.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D31-EK TM43xx"; + compatible = "atmel,sama5d31ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d31ek_pda7.dts - Device Tree file for SAMA5D31-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d31.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* Conflict with LCD pin mux */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D31-EK TM70xx"; + compatible = "atmel,sama5d31ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d31ek_revc.dts - Device Tree file for SAMA5D31-EK up to rev.C MB + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d31.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm.dtsi" + +/ { + model = "Atmel SAMA5D31-EK - rev.C"; + compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d31ek_revc_pda4.dts - Device Tree file for SAMA5D31-EK up to rev.C MB + * + PDA4.3" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d31.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D31-EK TM43xx - rev.C"; + compatible = "atmel,sama5d31ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d31ek_revc_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d31ek_revc_pda7.dts - Device Tree file for SAMA5D31-EK up to rev.C MB + * + PDA7" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d31.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D31-EK TM70xx - rev.C"; + compatible = "atmel,sama5d31ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d33ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ /dts-v1/; #include "sama5d33.dtsi" #include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ #include "sama5d3xdm.dtsi" / { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:45 @ }; }; + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + sound { status = "okay"; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d33ek_pda4.dts - Device Tree file for SAMA5D33-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d33.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D33-EK TM43xx"; + compatible = "atmel,sama5d33ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d33ek_pda7.dts - Device Tree file for SAMA5D33-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d33.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* Conflict with LCD pin mux */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D33-EK TM70xx"; + compatible = "atmel,sama5d33ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d33ek_revc.dts - Device Tree file for SAMA5D33-EK up to rev.C MB + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d33.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm.dtsi" + +/ { + model = "Atmel SAMA5D33-EK - rev.C"; + compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d33ek_revc_pda4.dts - Device Tree file for SAMA5D33-EK up to rev.C MB + * + PDA4.3" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d33.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D33-EK TM43xx - rev.C"; + compatible = "atmel,sama5d33ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d33ek_revc_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d33ek_revc_pda7.dts - Device Tree file for SAMA5D33-EK up to rev.C MB + * + PDA7" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d33.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D33-EK TM70xx - rev.C"; + compatible = "atmel,sama5d33ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d34ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ /dts-v1/; #include "sama5d34.dtsi" #include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ #include "sama5d3xdm.dtsi" / { Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d34ek_pda4.dts - Device Tree file for SAMA5D34-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d34.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D34-EK TM43xx"; + compatible = "atmel,sama5d34ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + + 24c256@50 { + compatible = "24c256"; + reg = <0x50>; + pagesize = <64>; + }; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d34ek_pda7.dts - Device Tree file for SAMA5D34-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d34.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* Conflict with LCD pin mux */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D34-EK TM70xx"; + compatible = "atmel,sama5d34ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + + 24c256@50 { + compatible = "24c256"; + reg = <0x50>; + pagesize = <64>; + }; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d34ek_revc.dts - Device Tree file for SAMA5D34-EK up to rev.C MB + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d34.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm.dtsi" + +/ { + model = "Atmel SAMA5D34-EK - rev.C"; + compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + + 24c256@50 { + compatible = "24c256"; + reg = <0x50>; + pagesize = <64>; + }; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d34ek_revc_pda4.dts - Device Tree file for SAMA5D34-EK up to rev.C MB + * + PDA4.3" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d34.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D34-EK TM43xx - rev.C"; + compatible = "atmel,sama5d34ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + + 24c256@50 { + compatible = "24c256"; + reg = <0x50>; + pagesize = <64>; + }; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d34ek_revc_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d34ek_revc_pda7.dts - Device Tree file for SAMA5D34-EK up to rev.C MB + * + PDA7" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d34.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D34-EK TM70xx - rev.C"; + compatible = "atmel,sama5d34ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + + 24c256@50 { + compatible = "24c256"; + reg = <0x50>; + pagesize = <64>; + }; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d35ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d35ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d35ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ /dts-v1/; #include "sama5d35.dtsi" #include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +#include "sama5d3xmb_isi_sensors.dtsi" /* Conflict with i2c0 & led d3 */ / { model = "Atmel SAMA5D35-EK"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ status = "okay"; }; - can0: can@f000c000 { + ssc0: ssc@f0008000 { status = "okay"; }; - i2c1: i2c@f0018000 { + can0: can@f000c000 { status = "okay"; }; - macb0: ethernet@f0028000 { + i2c0: i2c@f0014000 { + status = "disabled"; + }; + + i2c1: i2c@f0018000 { status = "okay"; }; - isi: isi@f0034000 { + macb0: ethernet@f0028000 { status = "okay"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:51 @ }; }; + /* Conflict with LCD pins */ gpio_keys { compatible = "gpio-keys"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:64 @ gpio-key,wakeup; }; }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + }; + + sound { + status = "okay"; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d35ek_revc.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d35ek_revc.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d35ek_revc.dts - Device Tree file for SAMA5D35-EK up to rev.C MB + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d35.dtsi" +#include "sama5d3xmb.dtsi" +/* #include "sama5d3xmb_revc_audio.dtsi" */ /* require i2c0 */ +#include "sama5d3xmb_isi_sensors.dtsi" /* Conflict with i2c0 & led d3 */ + +/ { + model = "Atmel SAMA5D35-EK - rev.C"; + compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "disabled"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "disabled"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + /* Conflict with LCD pins */ + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pb_user1 { + label = "pb_user1"; + gpios = <&pioE 27 GPIO_ACTIVE_HIGH>; + linux,code = <0x100>; + gpio-key,wakeup; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + }; + + sound { + status = "disable"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek.dts =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d36ek.dts +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ /dts-v1/; #include "sama5d36.dtsi" #include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi"*/ /* Conflict with i2c0 & led d3 */ #include "sama5d3xdm.dtsi" / { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:53 @ }; }; + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + sound { status = "okay"; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d36ek_pda4.dts - Device Tree file for SAMA5D36-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D36-EK TM43xx"; + compatible = "atmel,sama5d36ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d36ek_pda7.dts - Device Tree file for SAMA5D36-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> + * 2013 Josh Wu <josh.wu@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_audio.dtsi" +/* #include "sama5d3xmb_hdmi.dtsi" */ /* Conflict with LCD pin mux */ +/* #include "sama5d3xmb_isi_sensors.dtsi" */ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D36-EK TM70xx"; + compatible = "atmel,sama5d36ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d36ek_revc.dts - Device Tree file for SAMA5D36-EK up to rev.C MB + * + * Copyright (C) 2013 Atmel, + * 2013 Josh Wu <josh.wu@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi"*/ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm.dtsi" + +/ { + model = "Atmel SAMA5D36-EK - rev.C"; + compatible = "atmel,sama5d36ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc_pda4.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc_pda4.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d36ek_revc_pda4.dts - Device Tree file for SAMA5D36-EK up to rev.C MB + * + PDA4.3" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Josh Wu <josh.wu@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi"*/ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda4.dtsi" + +/ { + model = "Atmel SAMA5D36-EK TM43xx - rev.C"; + compatible = "atmel,sama5d36ek", "pda,tm43xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc_pda7.dts =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d36ek_revc_pda7.dts @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d36ek_revc_pda7.dts - Device Tree file for SAMA5D36-EK up to rev.C MB + * + PDA7" LCD + * + * Copyright (C) 2013 Atmel, + * 2013 Josh Wu <josh.wu@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xmb_revc_audio.dtsi" /* require i2c0 */ +/* #include "sama5d3xmb_revc_hdmi.dtsi" */ /* require i2c0 *//* need sil902x driver */ +/* #include "sama5d3xmb_isi_sensors.dtsi"*/ /* Conflict with i2c0 & led d3 */ +#include "sama5d3xdm_pda7.dtsi" + +/ { + model = "Atmel SAMA5D36-EK TM70xx - rev.C"; + compatible = "atmel,sama5d36ek", "pda,tm70xx", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + leds { + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d3.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:29 @ serial2 = &usart1; serial3 = &usart2; serial4 = &usart3; + serial5 = &uart0; gpio0 = &pioA; gpio1 = &pioB; gpio2 = &pioC; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ adc_op_clk: adc_op_clk{ compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <20000000>; + clock-frequency = <1000000>; }; }; + sram: sram@00300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x20000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:210 @ status = "disabled"; }; + uart0: serial@f0024000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf0024000 0x100>; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + clocks = <&uart0_clk>; + clock-names = "usart"; + status = "disabled"; + }; + pwm0: pwm@f002c000 { compatible = "atmel,sama5d3-pwm"; reg = <0xf002c000 0x300>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:230 @ status = "disabled"; }; - isi: isi@f0034000 { - compatible = "atmel,at91sam9g45-isi"; - reg = <0xf0034000 0x4000>; - interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>; - status = "disabled"; - }; - mmc1: mmc@f8000000 { compatible = "atmel,hsmci"; reg = <0xf8000000 0x600>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:305 @ atmel,adc-use-external-triggers; atmel,adc-vref = <3000>; atmel,adc-res = <10 12>; + atmel,adc-sample-hold-time = <11>; atmel,adc-res-names = "lowres", "highres"; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:559 @ }; isi { - pinctrl_isi: isi-0 { + pinctrl_isi_data_0_7: isi-0-data-0-7 { atmel,pins = <AT91_PIOA 16 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA16 periph C ISI_D0, conflicts with LCDDAT16 */ AT91_PIOA 17 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA17 periph C ISI_D1, conflicts with LCDDAT17 */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:571 @ AT91_PIOA 23 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA23 periph C ISI_D7, conflicts with LCDDAT23, PWML1 */ AT91_PIOC 30 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC30 periph C ISI_PCK, conflicts with UTXD0 */ AT91_PIOA 31 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA31 periph C ISI_HSYNC, conflicts with TWCK0, UTXD1 */ - AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */ - AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */ + AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */ + }; + + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + <AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */ AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC28 periph C ISI_PD9, conflicts with SPI1_NPCS3, PWMFI0 */ }; - pinctrl_isi_pck_as_mck: isi_pck_as_mck-0 { + + pinctrl_isi_data_10_11: isi-0-data-10-11 { atmel,pins = - <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */ + <AT91_PIOC 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC27 periph C ISI_PD10, conflicts with SPI1_NPCS2, TWCK1 */ + AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC26 periph C ISI_PD11, conflicts with SPI1_NPCS1, TWD1 */ }; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:760 @ }; }; + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* conflicts with PWMFI2, ISI_D8 */ + AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* conflicts with ISI_PCK */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* conflicts with TWD0, ISI_VSYNC */ + AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* conflicts with TWCK0, ISI_HSYNC */ + }; + }; + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1110 @ atmel,clk-output-range = <0 66000000>; }; + uart0_clk: uart0_clk { + #clock-cells = <0>; + reg = <16>; + atmel,clk-output-range = <0 66000000>; + }; + twi0_clk: twi0_clk { reg = <18>; #clock-cells = <0>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1306 @ usb0: gadget@00500000 { #address-cells = <1>; #size-cells = <0>; - compatible = "atmel,at91sam9rl-udc"; + compatible = "atmel,sama5d3-udc"; reg = <0x00500000 0x100000 0xf8030000 0x4000>; interrupts = <33 IRQ_TYPE_LEVEL_HIGH 2>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1424 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, - <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1433 @ compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00700000 0x100000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ehci_clk", "uhpck"; + clocks = <&utmi>, <&uhphs_clk>; + clock-names = "usb_clk", "ehci_clk"; + status = "disabled"; + }; + + isi: isi@f0034000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xf0034000 0x4000>; + interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; }; nand0: nand@60000000 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1477 @ #address-cells = <1>; #size-cells = <1>; reg = < - 0x70000000 0x10000000 /* NFC Command Registers */ + 0x70000000 0x08000000 /* NFC Command Registers */ 0xffffc000 0x00000070 /* NFC HSMC regs */ 0x00200000 0x00100000 /* NFC SRAM banks */ >; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3_lcd.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d3_lcd.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3_lcd.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:18 @ apb { pinctrl@fffff200 { lcd { - pinctrl_lcd: lcd-0 { + pinctrl_lcd_pwm: lcd-pwm-0 { + atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */ + }; + + pinctrl_lcd_base: lcd-base-0 { + atmel,pins = + <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */ + AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */ + AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDISP */ + AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */ + AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */ + }; + + pinctrl_lcd_rgb444: lcd-rgb-0 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */ + }; + + pinctrl_lcd_rgb565: lcd-rgb-1 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */ + }; + + pinctrl_lcd_rgb666: lcd-rgb-2 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD17 pin */ + }; + + pinctrl_lcd_rgb666_alt: lcd-rgb-2-alt { atmel,pins = - <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA24 periph A LCDPWM */ - AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA26 periph A LCDVSYNC */ - AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA27 periph A LCDHSYNC */ - AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA25 periph A LCDDISP */ - AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA29 periph A LCDDEN */ - AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA28 periph A LCDPCK */ - AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A LCDD0 pin */ - AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA1 periph A LCDD1 pin */ - AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA2 periph A LCDD2 pin */ - AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA3 periph A LCDD3 pin */ - AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA4 periph A LCDD4 pin */ - AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA5 periph A LCDD5 pin */ - AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA6 periph A LCDD6 pin */ - AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA7 periph A LCDD7 pin */ - AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA8 periph A LCDD8 pin */ - AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A LCDD9 pin */ - AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA10 periph A LCDD10 pin */ - AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A LCDD11 pin */ - AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A LCDD12 pin */ - AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A LCDD13 pin */ - AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A LCDD14 pin */ - AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A LCDD15 pin */ - AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC14 periph C LCDD16 pin */ - AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC13 periph C LCDD17 pin */ - AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC12 periph C LCDD18 pin */ - AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC11 periph C LCDD19 pin */ - AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC10 periph C LCDD20 pin */ - AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC15 periph C LCDD21 pin */ - AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PE27 periph C LCDD22 pin */ - AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PE28 periph C LCDD23 pin */ + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* LCDD17 pin */ }; + + pinctrl_lcd_rgb888: lcd-rgb-3 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + + pinctrl_lcd_rgb888_alt: lcd-rgb-3-alt { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + }; + }; + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xcm.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d3xcm.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xcm.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:125 @ d2 { label = "d2"; gpios = <&pioE 25 GPIO_ACTIVE_LOW>; /* PE25, conflicts with A25, RXD2 */ + linux,default-trigger = "heartbeat"; }; }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d3xdm.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ }; }; + hlcdc: hlcdc@f0030000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888_alt>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + adc0: adc@f8018000 { atmel,adc-ts-wires = <4>; atmel,adc-ts-pressure-threshold = <10000>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:57 @ }; }; }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "foxlink,fl500wvr00-a0t", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm_pda4.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm_pda4.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d3xdm_pda4.dtsi - Device Tree file for SAMA5 display module + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <30 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + atmel_mxt_ts@4a { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4a>; + interrupt-parent = <&pioE>; + interrupts = <31 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; + }; + + hlcdc: hlcdc@f0030000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888_alt>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + pinctrl@fffff200 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 30 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE30 GPIO with pull up deglith */ + }; + + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE31 GPIO with pull up deglith */ + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "innolux,at043tn24", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm_pda7.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xdm_pda7.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d3xdm_pda7.dtsi - Device Tree file for SAMA5 display module + * + * Copyright (C) 2014 Atmel, + * 2014 Ludovic Desroches <ludovic.desroches@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + qt1070: keyboard@1b { + compatible = "qt1070"; + reg = <0x1b>; + interrupt-parent = <&pioE>; + interrupts = <30 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; + }; + + atmel_mxt_ts@4c { + compatible = "atmel,atmel_mxt_ts"; + reg = <0x4c>; + interrupt-parent = <&pioE>; + interrupts = <31 0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mxt_ts>; + }; + }; + + hlcdc: hlcdc@f0030000 { + status = "okay"; + + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb666_alt>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + adc0: adc@f8018000 { + atmel,adc-clock-rate = <1000000>; + /* atmel,adc-ts-wires = <4>;*/ + /* atmel,adc-ts-pressure-threshold = <10000>;*/ + status = "okay"; + }; + + pinctrl@fffff200 { + board { + pinctrl_qt1070_irq: qt1070_irq { + atmel,pins = + <AT91_PIOE 30 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE30 GPIO with pull up deglith */ + }; + + pinctrl_mxt_ts: mxt_irq { + atmel,pins = + <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE31 GPIO with pull up deglith */ + }; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&hlcdc_pwm 0 50000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <&bl_reg>; + status = "okay"; + }; + + bl_reg: backlight_regulator { + compatible = "regulator-fixed"; + regulator-name = "backlight-power-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + panel: panel { + compatible = "shelly,sca07010-bfn-lnn", "simple-panel"; + backlight = <&backlight>; + power-supply = <&panel_reg>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + panel_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_panel_output>; + }; + }; + }; + + panel_reg: panel_regulator { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + status = "okay"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_audio.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_audio.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d3xmb_audio.dtsi - Device Tree file for audio on mother board + * + * Copyright (C) 2015 Atmel, + * 2015 Bo Shen <voice.shen@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + wm8904: wm8904@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&pck0>; + clock-names = "mclk"; + }; + }; + }; + }; + + sound { + compatible = "atmel,asoc-wm8904"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_audio_mck>; + + atmel,model = "wm8904 @ SAMA5D3EK"; + atmel,audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Mic", "MICBIAS", + "IN1L", "Mic"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8904>; + + status = "disabled"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d3xmb.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:41 @ atmel,clk-from-rk-pin; }; - /* - * i2c0 conflicts with ISI: - * disable it to allow the use of ISI - * can not enable audio when i2c0 disabled - */ - i2c0: i2c@f0014000 { - wm8904: wm8904@1a { - compatible = "wm8904"; - reg = <0x1a>; - clocks = <&pck0>; - clock-names = "mclk"; - }; - }; - usart1: serial@f0020000 { dmas = <0>, <0>; /* Do not use DMA for usart1 */ pinctrl-names = "default"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:48 @ status = "okay"; }; - isi: isi@f0034000 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_isi &pinctrl_isi_pck_as_mck &pinctrl_isi_power &pinctrl_isi_reset>; - }; - mmc1: mmc@f8000000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ #address-cells = <1>; #size-cells = <0>; phy0: ethernet-phy@1 { - interrupt-parent = <&pioE>; - interrupts = <30 IRQ_TYPE_EDGE_FALLING>; + /*interrupt-parent = <&pioE>;*/ + /*interrupts = <30 IRQ_TYPE_EDGE_FALLING>;*/ reg = <1>; }; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:101 @ <AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD30 periph B */ }; - pinctrl_isi_reset: isi_reset-0 { + pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 { + atmel,pins = + <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */ + }; + + pinctrl_sensor_reset: sensor_reset-0 { atmel,pins = <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE24 gpio */ }; - pinctrl_isi_power: isi_power-0 { + pinctrl_sensor_power: sensor_power-0 { atmel,pins = <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE29 gpio */ }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:153 @ status = "okay"; }; }; - - sound { - compatible = "atmel,asoc-wm8904"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pck0_as_audio_mck>; - - atmel,model = "wm8904 @ SAMA5D3EK"; - atmel,audio-routing = - "Headphone Jack", "HPOUTL", - "Headphone Jack", "HPOUTR", - "IN2L", "Line In Jack", - "IN2R", "Line In Jack", - "MICBIAS", "IN1L", - "IN1L", "Mic"; - - atmel,ssc-controller = <&ssc0>; - atmel,audio-codec = <&wm8904>; - - status = "disabled"; - }; }; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_hdmi.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_hdmi.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for HDMI on sama5d3x mother board + * + * Copyright (C) 2015 Atmel, + * 2015 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + sil9022: hdmi-encoder@39 { + compatible = "sil,sil9022"; + reg = <0x39>; + reset-gpio = <&pioC 31 GPIO_ACTIVE_LOW>; + interrupt-extended = <&pioC 29 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sil9022_irq>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_hdmi_output>; + }; + }; + }; + }; + + hlcdc: hlcdc@f0030000 { + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888_alt>; + + port@0 { + hlcdc_hdmi_output: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_input>; + }; + }; + }; + }; + + pinctrl@fffff200 { + board { + pinctrl_sil9022_irq: sil9022_irq-0 { + atmel,pins = + <AT91_PIOC 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_isi_sensors.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_isi_sensors.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d3xmb_isi_sensors.dts - Device Tree file for camera sensor boards which + * can be insert in SAMA5D3x mother board + * + * Copyright (C) 2015 Atmel, + * 2015 Josh Wu <josh.wu@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c1: i2c@f0018000 { + ov9740: camera@0x10 { + compatible = "ovti,ov9740"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov9740_0: endpoint { + remote-endpoint = <&isi_3>; + bus-width = <8>; + }; + }; + }; + + ov7740: camera@0x21 { + compatible = "ovti,ov7740"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov7740_0: endpoint { + remote-endpoint = <&isi_2>; + bus-width = <8>; + }; + }; + }; + + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + /* use pck1 for the master clock of ov2640 */ + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + + ov5640: camera@0x3c { + compatible = "ovti,ov5642"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + clocks = <&pck1>; + clock-names = "xvclk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov5640_0: endpoint { + remote-endpoint = <&isi_1>; + bus-width = <8>; + }; + }; + }; + }; + }; + + isi: isi@f0034000 { + status = "okay"; + port { + isi_0: endpoint@0 { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + }; + + isi_1: endpoint@1 { + remote-endpoint = <&ov5640_0>; + bus-width = <8>; + }; + + isi_2: endpoint@2 { + remote-endpoint = <&ov7740_0>; + bus-width = <8>; + }; + + isi_3: endpoint@3 { + remote-endpoint = <&ov9740_0>; + bus-width = <8>; + }; + }; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_revc_audio.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_revc_audio.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * sama5d3xmb_revc_audio.dtsi - Device Tree file for audio on revision C mother board + * + * Copyright (C) 2015 Atmel, + * 2015 Bo Shen <voice.shen@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c0: i2c@f0014000 { + wm8904: wm8904@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&pck0>; + clock-names = "mclk"; + }; + }; + }; + }; + + sound { + compatible = "atmel,asoc-wm8904"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_audio_mck>; + + atmel,model = "wm8904 @ SAMA5D3EK"; + atmel,audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Mic", "MICBIAS", + "IN1L", "Mic"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8904>; + + status = "disabled"; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_revc_hdmi.dtsi =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d3xmb_revc_hdmi.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Device Tree file for HDMI on sama5d3x up to rev.C mother board + * + * Copyright (C) 2015 Atmel, + * 2015 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + ahb { + apb { + i2c0: i2c@f0014000 { + sil9022: hdmi-encoder@39 { + compatible = "sil,sil9022"; + reg = <0x39>; + reset-gpio = <&pioC 31 GPIO_ACTIVE_LOW>; + interrupt-extended = <&pioC 29 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sil9022_irq>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_input: endpoint@0 { + reg = <0>; + remote-endpoint = <&hlcdc_hdmi_output>; + }; + }; + }; + }; + + hlcdc: hlcdc@f0030000 { + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888_alt>; + + port@0 { + hlcdc_hdmi_output: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_input>; + }; + }; + }; + }; + + pinctrl@fffff200 { + board { + pinctrl_sil9022_irq: sil9022_irq-0 { + atmel,pins = + <AT91_PIOC 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + }; + }; + }; + }; +}; Index: linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d4.dtsi =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/boot/dts/sama5d4.dtsi +++ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/sama5d4.dtsi @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ * licensing only applies to this file, and not this project as a * whole. * - * a) This library is free software; you can redistribute it and/or + * a) This file 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 library is distributed in the hope that it will be useful, + * This file 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. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:48 @ #include "skeleton.dtsi" #include <dt-bindings/clock/at91.h> +#include <dt-bindings/dma/at91.h> #include <dt-bindings/pinctrl/at91.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/gpio/gpio.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:62 @ serial0 = &usart3; serial1 = &usart4; serial2 = &usart2; + serial3 = &usart0; + serial4 = &usart1; + serial5 = &uart0; + serial6 = &uart1; gpio0 = &pioA; gpio1 = &pioB; gpio2 = &pioC; + gpio3 = &pioD; gpio4 = &pioE; tcb0 = &tcb0; tcb1 = &tcb1; i2c2 = &i2c2; + pwm0 = &pwm0; + ssc0 = &ssc0; + ssc1 = &ssc1; }; cpus { #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:114 @ }; }; + ns_sram: sram@00210000 { + compatible = "mmio-sram"; + reg = <0x00210000 0x10000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + vdec0: vdec@00300000 { + compatible = "on2,g1"; + reg = <0x00300000 0x1000>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; + clocks = <&vdec_clk>; + clock-names = "vdec_clk"; + status = "disabled"; + }; + usb0: gadget@00400000 { #address-cells = <1>; #size-cells = <0>; - compatible = "atmel,at91sam9rl-udc"; + compatible = "atmel,sama5d3-udc"; reg = <0x00400000 0x100000 0xfc02c000 0x4000>; interrupts = <47 IRQ_TYPE_LEVEL_HIGH 2>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:268 @ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x100000>; interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, - <&uhpck>; - clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:277 @ compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00600000 0x100000>; interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&uhpck>; - clock-names = "usb_clk", "ehci_clk", "uhpck"; + clocks = <&utmi>, <&uhphs_clk>; + clock-names = "usb_clk", "ehci_clk"; status = "disabled"; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:291 @ }; nand0: nand@80000000 { - compatible = "atmel,at91rm9200-nand"; + compatible = "atmel,sama5d4-nand", "atmel,at91rm9200-nand"; #address-cells = <1>; #size-cells = <1>; ranges; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:312 @ #address-cells = <1>; #size-cells = <1>; reg = < - 0x90000000 0x10000000 /* NFC Command Registers */ + 0x90000000 0x08000000 /* NFC Command Registers */ 0xfc05c000 0x00000070 /* NFC HSMC regs */ 0x00100000 0x00100000 /* NFC SRAM banks */ >; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:321 @ }; }; + isi: isi@f0008000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xf0008000 0x4000>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + apb { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + hlcdc: hlcdc@f0000000 { + compatible = "atmel,sama5d4-hlcdc"; + reg = <0xf0000000 0x4000>; + interrupts = <51 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; + + dma1: dma-controller@f0004000 { + compatible = "atmel,sama5d4-dma"; + reg = <0xf0004000 0x200>; + interrupts = <50 IRQ_TYPE_LEVEL_HIGH 0>; + #dma-cells = <1>; + clocks = <&dma1_clk>; + clock-names = "dma_clk"; + }; + ramc0: ramc@f0010000 { compatible = "atmel,sama5d3-ddramc"; reg = <0xf0010000 0x200>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:386 @ clock-names = "ddrck", "mpddr"; }; + dma0: dma-controller@f0014000 { + compatible = "atmel,sama5d4-dma"; + reg = <0xf0014000 0x200>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH 0>; + #dma-cells = <1>; + clocks = <&dma0_clk>; + clock-names = "dma_clk"; + }; + pmc: pmc@f0018000 { compatible = "atmel,sama5d3-pmc"; reg = <0xf0018000 0x120>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:522 @ lcdck: lcdck { #clock-cells = <0>; - reg = <4>; - clocks = <&smd>; + reg = <3>; + clocks = <&mck>; }; smdck: smdck { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:831 @ reg = <50>; }; - lcd_clk: lcd_clk { + lcdc_clk: lcdc_clk { #clock-cells = <0>; reg = <51>; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:847 @ compatible = "atmel,hsmci"; reg = <0xf8000000 0x600>; interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(0))>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3>; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:860 @ clock-names = "mci_clk"; }; + uart0: serial@f8004000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8004000 0x100>; + interrupts = <27 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(22))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(23))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + clocks = <&uart0_clk>; + clock-names = "usart"; + status = "disabled"; + }; + + ssc0: ssc@f8008000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xf8008000 0x4000>; + interrupts = <48 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(26))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(27))>; + dma-names = "tx", "rx"; + clocks = <&ssc0_clk>; + clock-names = "pclk"; + status = "disabled"; + }; + + pwm0: pwm@f800c000 { + compatible = "atmel,sama5d3-pwm"; + reg = <0xf800c000 0x300>; + interrupts = <43 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + clocks = <&pwm_clk>; + status = "disabled"; + }; + spi0: spi@f8010000 { #address-cells = <1>; #size-cells = <0>; compatible = "atmel,at91rm9200-spi"; reg = <0xf8010000 0x100>; interrupts = <37 IRQ_TYPE_LEVEL_HIGH 3>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(10))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(11))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0>; clocks = <&spi0_clk>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:929 @ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8014000 0x4000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(2))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(3))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c0>; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:958 @ interrupts = <54 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_macb0_rmii>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&macb0_clk>, <&macb0_clk>; clock-names = "hclk", "pclk"; status = "disabled"; }; + sha@fc050000 { + compatible = "atmel,at91sam9g46-sha"; + reg = <0xfc050000 0x100>; + interrupts = <15 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(44))>; + dma-names = "tx"; + clocks = <&sha_clk>; + clock-names = "sha_clk"; + status = "okay"; + }; + + aes@fc044000 { + compatible = "atmel,at91sam9g46-aes"; + reg = <0xfc044000 0x100>; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(41))>, + <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(40))>; + dma-names = "tx", "rx"; + clocks = <&aes_clk>; + clock-names = "aes_clk"; + status = "okay"; + }; + + tdes@fc04c000 { + compatible = "atmel,at91sam9g46-tdes"; + reg = <0xfc04c000 0x100>; + interrupts = <14 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(42))>, + <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(43))>; + dma-names = "tx", "rx"; + clocks = <&tdes_clk>; + clock-names = "tdes_clk"; + status = "okay"; + }; + i2c2: i2c@f8024000 { compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8024000 0x4000>; - interrupts = <34 4 6>; + interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(6))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(7))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; #address-cells = <1>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1024 @ status = "disabled"; }; + usart0: serial@f802c000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf802c000 0x100>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(36))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(37))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts &pinctrl_usart0_cts>; + clocks = <&usart0_clk>; + clock-names = "usart"; + status = "disabled"; + }; + + usart1: serial@f8030000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8030000 0x100>; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(38))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(39))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts &pinctrl_usart1_cts>; + clocks = <&usart1_clk>; + clock-names = "usart"; + status = "disabled"; + }; + mmc1: mmc@fc000000 { compatible = "atmel,hsmci"; reg = <0xfc000000 0x600>; interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(1))>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>; status = "disabled"; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1077 @ clock-names = "mci_clk"; }; + uart1: serial@fc004000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xfc004000 0x100>; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(24))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(25))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + clocks = <&uart1_clk>; + clock-names = "usart"; + status = "disabled"; + }; + usart2: serial@fc008000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfc008000 0x100>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(16))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(17))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rts &pinctrl_usart2_cts>; clocks = <&usart2_clk>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1117 @ compatible = "atmel,at91sam9260-usart"; reg = <0xfc00c000 0x100>; interrupts = <30 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(18))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(19))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart3>; clocks = <&usart3_clk>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1135 @ compatible = "atmel,at91sam9260-usart"; reg = <0xfc010000 0x100>; interrupts = <31 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(20))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(21))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart4>; clocks = <&usart4_clk>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1149 @ status = "disabled"; }; + ssc1: ssc@fc014000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xfc014000 0x4000>; + interrupts = <49 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(28))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(29))>; + dma-names = "tx", "rx"; + clocks = <&ssc1_clk>; + clock-names = "pclk"; + status = "disabled"; + }; + + spi1: spi@fc018000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91rm9200-spi"; + reg = <0xfc018000 0x100>; + interrupts = <38 IRQ_TYPE_LEVEL_HIGH 3>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(12))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(13))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&spi1_clk>; + clock-names = "spi_clk"; + status = "disabled"; + }; + + spi2: spi@fc01c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91rm9200-spi"; + reg = <0xfc01c000 0x100>; + interrupts = <39 IRQ_TYPE_LEVEL_HIGH 3>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(14))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(15))>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2>; + clocks = <&spi2_clk>; + clock-names = "spi_clk"; + status = "disabled"; + }; + tcb1: timer@fc020000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xfc020000 0x100>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1274 @ pit: timer@fc068630 { compatible = "atmel,at91sam9260-pit"; - reg = <0xfc068630 0xf>; + reg = <0xfc068630 0x10>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>; clocks = <&h32ck>; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1333 @ #address-cells = <1>; #size-cells = <1>; compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfc06a000 0xfc06a000 0x4000>; + ranges = <0xfc068000 0xfc068000 0x100 + 0xfc06a000 0xfc06a000 0x4000>; /* WARNING: revisit as pin spec has changed */ atmel,mux-mask = < /* A B C */ 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */ 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */ 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */ - 0x00000000 0x00000000 0x00000000 /* pioD */ + 0x0003ff00 0x8002a800 0x00000000 /* pioD */ 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */ >; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1378 @ clocks = <&pioC_clk>; }; + pioD: gpio@fc068000 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfc068000 0x100>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&pioD_clk>; + }; + pioE: gpio@fc06d000 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfc06d000 0x100>; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1452 @ }; }; + lcd { + pinctrl_lcd_pwm: lcd-pwm-0 { + atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPWM */ + }; + + pinctrl_lcd_base: lcd-base-0 { + atmel,pins = + <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDVSYNC */ + AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDHSYNC */ + AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDDEN */ + AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */ + }; + + pinctrl_lcd_rgb444: lcd-rgb-0 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */ + }; + + pinctrl_lcd_rgb565: lcd-rgb-1 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */ + }; + + pinctrl_lcd_rgb666: lcd-rgb-2 { + atmel,pins = + <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + + pinctrl_lcd_rgb777: lcd-rgb-3 { + atmel,pins = + /* LCDDAT0 conflicts with TMS */ + <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + /* LCDDAT8 conflicts with TCK */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + /* LCDDAT16 conflicts with NTRST */ + AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + + pinctrl_lcd_rgb888: lcd-rgb-4 { + atmel,pins = + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD15 pin */ + AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD16 pin */ + AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD17 pin */ + AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD18 pin */ + AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD19 pin */ + AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD20 pin */ + AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD21 pin */ + AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* LCDD22 pin */ + AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */ + }; + }; + macb0 { pinctrl_macb0_rmii: macb0_rmii-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1653 @ }; }; + isi { + pinctrl_isi_data_0_7: isi-0-data-0-7 { + atmel,pins = + <AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D0 */ + AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D1 */ + AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D2 */ + AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D3 */ + AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D4 */ + AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D5 */ + AT91_PIOC 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D6 */ + AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* ISI_D7 */ + AT91_PIOB 1 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_PCK, conflict with G0_RXCK */ + AT91_PIOB 3 AT91_PERIPH_C AT91_PINCTRL_NONE /* ISI_VSYNC */ + AT91_PIOB 4 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_HSYNC */ + }; + + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC0 periph C ISI_D8, conflicts with SPI0_MISO, PWMH2 */ + AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC1 periph C ISI_D9, conflicts with SPI0_MOSI, PWML2 */ + }; + + pinctrl_isi_data_10_11: isi-0-data-10-11 { + atmel,pins = + <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC2 periph C ISI_D10, conflicts with SPI0_SPCK, PWMH3 */ + AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC3 periph C ISI_D11, conflicts with SPI0_NPCS0, PWML3 */ + }; + }; + spi0 { pinctrl_spi0: spi0-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1692 @ }; }; + spi1 { + pinctrl_spi1: spi1-0 { + atmel,pins = + <AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI1_MISO */ + AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI1_MOSI */ + AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* SPI1_SPCK */ + >; + }; + }; + + spi2 { + pinctrl_spi2: spi2-0 { + atmel,pins = + <AT91_PIOD 11 AT91_PERIPH_B AT91_PINCTRL_NONE /* SPI2_MISO conflicts with RTS0 */ + AT91_PIOD 13 AT91_PERIPH_B AT91_PINCTRL_NONE /* SPI2_MOSI conflicts with TXD0 */ + AT91_PIOD 15 AT91_PERIPH_B AT91_PINCTRL_NONE /* SPI2_SPCK conflicts with RTS1 */ + >; + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <AT91_PIOE 29 AT91_PERIPH_B AT91_PINCTRL_NONE /* RXD */ + AT91_PIOE 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* TXD */ + >; + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <AT91_PIOC 25 AT91_PERIPH_C AT91_PINCTRL_NONE /* RXD */ + AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_PULL_UP /* TXD */ + >; + }; + }; + + usart0 { + pinctrl_usart0: usart0-0 { + atmel,pins = + <AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* RXD */ + AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* TXD */ + >; + }; + pinctrl_usart0_rts: usart0_rts-0 { + atmel,pins = <AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; + }; + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = <AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; + }; + }; + + usart1 { + pinctrl_usart1: usart1-0 { + atmel,pins = + <AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* RXD */ + AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* TXD */ + >; + }; + pinctrl_usart1_rts: usart1_rts-0 { + atmel,pins = <AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; + }; + pinctrl_usart1_cts: usart1_cts-0 { + atmel,pins = <AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; + }; + }; + usart2 { pinctrl_usart2: usart2-0 { atmel,pins = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1798 @ atmel,pins = <AT91_PIOE 0 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* conflicts with A0/NBS0, MCI0_CDB */ }; }; + + ssc0 { + pinctrl_ssc0_tx: ssc0_tx { + atmel,pins = + <AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB27 periph B TK0 */ + AT91_PIOB 31 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB31 periph B TF0 */ + AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB28 periph B TD0 */ + }; + + pinctrl_ssc0_rx: ssc0_rx { + atmel,pins = + <AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB26 periph B RK0 */ + AT91_PIOB 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB30 periph B RF0 */ + AT91_PIOB 29 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB29 periph B RD0 */ + }; + }; + + ssc1 { + pinctrl_ssc1_tx: ssc1_tx { + atmel,pins = + <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC19 periph B TK1 */ + AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC20 periph B TF1 */ + AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC21 periph B TD1 */ + }; + + pinctrl_ssc1_rx: ssc1_rx { + atmel,pins = + <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC24 periph B RK1 */ + AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC22 periph B RF1 */ + AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC23 periph B RD1 */ + }; + }; }; aic: interrupt-controller@fc06e000 { Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91_dt_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91_dt_defconfig +++ linux-3.18.13-rt10-r7s4/arch/arm/configs/at91_dt_defconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ -# CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:26 @ CONFIG_SOC_AT91SAM9N12=y CONFIG_MACH_AT91RM9200_DT=y CONFIG_MACH_AT91SAM9_DT=y CONFIG_AT91_TIMER_HZ=128 +CONFIG_AT91_SLOW_CLOCK=y CONFIG_AEABI=y +CONFIG_CMA=y CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw" -CONFIG_KEXEC=y CONFIG_AUTO_ZRELADDR=y +CONFIG_CPU_IDLE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:57 @ CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_BEET is not set CONFIG_IPV6_SIT_6RD=y +CONFIG_CAN=y +CONFIG_CAN_AT91=y CONFIG_CFG80211=y +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_DMA_CMA=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_CFI=y +CONFIG_MTD_M25P80=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_SPI_NOR=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_GLUEBI=y CONFIG_BLK_DEV_LOOP=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:86 @ CONFIG_BLK_DEV_RAM_COUNT=4 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_SSC=y +CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set CONFIG_MACB=y # CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_DM9000=y +# CONFIG_NET_VENDOR_CIRRUS is not set # CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON 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_QUALCOMM is not set +# CONFIG_NET_VENDOR_SAMSUNG 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_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_DAVICOM_PHY=y CONFIG_MICREL_PHY=y +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_ATMEL_SMARTCONNECT=y +CONFIG_WILC1000=m +CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER=y +CONFIG_USB_ZD1201=m CONFIG_RTL8187=m +CONFIG_ATH_CARDS=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_AR5523=m CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_SPI=m CONFIG_RT2X00=m CONFIG_RT2500USB=m CONFIG_RT73USB=m CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_RT55XX=y CONFIG_RT2800USB_UNKNOWN=y CONFIG_RTL8192CU=m # CONFIG_RTLWIFI_DEBUG is not set +CONFIG_WL_TI=y +CONFIG_WL1251=m +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_ZD1211RW=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_USB=m +CONFIG_RSI_91X=m +# CONFIG_RSI_DEBUGFS is not set CONFIG_INPUT_POLLDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=480 @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:155 @ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272 CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_QT1070=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y CONFIG_I2C_AT91=y CONFIG_I2C_GPIO=y CONFIG_SPI=y CONFIG_SPI_ATMEL=y +CONFIG_SPI_GPIO=y +CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_AT91_POWEROFF=y +CONFIG_POWER_RESET_AT91_RESET=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_AT91SAM9X_WATCHDOG=y CONFIG_SSB=m +CONFIG_MFD_ATMEL_HLCDC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_INPUT_EVDEV is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_VIDEO_ATMEL_ISI=y +CONFIG_SOC_CAMERA_OV2640=y +CONFIG_SOC_CAMERA_OV5642=y +CONFIG_SOC_CAMERA_OV7740=y +CONFIG_SOC_CAMERA_OV9740=y +CONFIG_DRM=y +CONFIG_DRM_ATMEL_HLCDC=y +CONFIG_DRM_PANEL_SIMPLE=y CONFIG_FB=y CONFIG_FB_ATMEL=y CONFIG_BACKLIGHT_LCD_SUPPORT=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:210 @ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_ATMEL_LCDC=y # CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_LOGO=y +CONFIG_BACKLIGHT_PWM=y CONFIG_SOUND=y CONFIG_SND=y +CONFIG_SND_ATMEL_AC97C=y CONFIG_SND_SOC=y CONFIG_SND_ATMEL_SOC=y CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:234 @ CONFIG_USB_AT91=y CONFIG_USB_ATMEL_USBA=y CONFIG_USB_G_SERIAL=y CONFIG_MMC=y +# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ATMELMCI=y CONFIG_MMC_SPI=y CONFIG_NEW_LEDS=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:246 @ CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_RV3029C2=y CONFIG_RTC_DRV_AT91RM9200=y CONFIG_RTC_DRV_AT91SAM9=y CONFIG_DMADEVICES=y CONFIG_AT_HDMAC=y +CONFIG_DMATEST=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_IIO=y CONFIG_AT91_ADC=y CONFIG_PWM=y CONFIG_PWM_ATMEL=y +CONFIG_PWM_ATMEL_HLCDC_PWM=y +CONFIG_PWM_ATMEL_TCB=y +CONFIG_RESET_CONTROLLER=y CONFIG_EXT4_FS=y CONFIG_FANOTIFY=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_ADVANCED_COMPR=y CONFIG_NFS_FS=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:275 @ CONFIG_NLS_UTF8=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y # CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FTRACE is not set CONFIG_DEBUG_USER=y CONFIG_CRYPTO=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:284 @ CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m -# CONFIG_CRYPTO_HW is not set +CONFIG_CRYPTO_DEV_ATMEL_AES=y +CONFIG_CRYPTO_DEV_ATMEL_TDES=y +CONFIG_CRYPTO_DEV_ATMEL_SHA=y CONFIG_CRC_CCITT=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=m CONFIG_AVERAGE=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_ACORN_8x8=y -CONFIG_FONT_MINI_4x6=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91rm9200_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91rm9200_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_USER_NS=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91RM9200=y -CONFIG_MACH_ONEARM=y -CONFIG_MACH_AT91RM9200EK=y -CONFIG_MACH_CSB337=y -CONFIG_MACH_CSB637=y -CONFIG_MACH_CARMEVA=y -CONFIG_MACH_ATEB9200=y -CONFIG_MACH_KB9200=y -CONFIG_MACH_PICOTUX2XX=y -CONFIG_MACH_KAFA=y -CONFIG_MACH_ECBAT91=y -CONFIG_MACH_YL9200=y -CONFIG_MACH_CPUAT91=y -CONFIG_MACH_ECO920=y -CONFIG_MTD_AT91_DATAFLASH_CARD=y -CONFIG_AT91_TIMER_HZ=100 -# CONFIG_ARM_THUMB is not set -CONFIG_PCCARD=y -CONFIG_AT91_CF=y -CONFIG_AEABI=y -# CONFIG_COMPACTION is not set -CONFIG_ZBOOT_ROM_TEXT=0x10000000 -CONFIG_ZBOOT_ROM_BSS=0x20040000 -CONFIG_KEXEC=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_FPE_NWFPE=y -CONFIG_BINFMT_MISC=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_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PLATRAM=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_NAND_PLATFORM=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_ARM_AT91_ETHER=y -CONFIG_DAVICOM_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_MICREL_PHY=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91RM9200_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y -CONFIG_FB_S1D13XXX=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_LOGO=y -CONFIG_USB=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_GADGET=y -CONFIG_USB_AT91=y -CONFIG_USB_G_SERIAL=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -CONFIG_EXT4_FS=y -CONFIG_AUTOFS4_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_FTRACE is not set -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_SHA1=y -CONFIG_XZ_DEC_ARMTHUMB=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91sam9260_9g20_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91sam9260_9g20_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9260=y -CONFIG_MACH_AT91SAM9260EK=y -CONFIG_MACH_CAM60=y -CONFIG_MACH_SAM9_L9260=y -CONFIG_MACH_AFEB9260=y -CONFIG_MACH_CPU9260=y -CONFIG_MACH_FLEXIBITY=y -CONFIG_MACH_AT91SAM9G20EK=y -CONFIG_MACH_AT91SAM9G20EK_2MMC=y -CONFIG_MACH_CPU9G20=y -CONFIG_MACH_ACMENETUSFOXG20=y -CONFIG_MACH_PORTUXG20=y -CONFIG_MACH_STAMP9G20=y -CONFIG_MACH_PCONTROL_G20=y -CONFIG_MACH_GSIA18S=y -CONFIG_MACH_SNAPPER_9260=y -CONFIG_MACH_AT91SAM9_DT=y -CONFIG_AT91_SLOW_CLOCK=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" -CONFIG_AUTO_ZRELADDR=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_EEPROM_AT25=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_MACB=y -# CONFIG_NET_VENDOR_BROADCOM 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_SMSC_PHY=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=y -CONFIG_GPIO_SYSFS=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_RESET=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_SEQUENCER=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_VERBOSE_PROCFS is not set -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_AT91=y -CONFIG_USB_G_SERIAL=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_RV3029C2=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_IIO=y -CONFIG_AT91_ADC=y -CONFIG_EXT4_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_FTRACE is not set -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91sam9261_9g10_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91sam9261_9g10_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_KERNEL_LZMA=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9261=y -CONFIG_MACH_AT91SAM9261EK=y -CONFIG_MACH_AT91SAM9G10EK=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" -CONFIG_AUTO_ZRELADDR=y -CONFIG_VFP=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -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_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_CFG80211=y -CONFIG_MAC80211=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_NETDEVICES=y -CONFIG_DM9000=y -CONFIG_USB_ZD1201=m -CONFIG_RTL8187=m -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_SPI=m -CONFIG_RT2X00=m -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -CONFIG_ZD1211RW=m -CONFIG_INPUT_POLLDEV=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_RESET=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_ATMEL_LCDC=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_LOGO=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_SEQUENCER=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=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_AT73C213=y -CONFIG_SND_USB_AUDIO=m -# CONFIG_USB_HID is not set -CONFIG_USB=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_AT91=y -CONFIG_USB_G_SERIAL=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_SQUASHFS=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -CONFIG_CRC_CCITT=m Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91sam9263_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91sam9263_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9263=y -CONFIG_MACH_AT91SAM9263EK=y -CONFIG_MTD_AT91_DATAFLASH_CARD=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" -CONFIG_AUTO_ZRELADDR=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_NFTL=y -CONFIG_NFTL_RW=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_BLOCK2MTD=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_ATMEL_TCLIB=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_NETDEVICES=y -CONFIG_MACB=y -CONFIG_SMSC_PHY=y -# CONFIG_WLAN is not set -CONFIG_INPUT_POLLDEV=m -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_GPIO_SYSFS=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_RESET=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_LOGO=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_SEQUENCER=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=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_ATMEL_AC97C=y -# CONFIG_SND_SPI is not set -CONFIG_SND_USB_AUDIO=m -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_ATMEL_USBA=y -CONFIG_USB_G_SERIAL=y -CONFIG_MMC=y -CONFIG_SDIO_UART=m -CONFIG_MMC_ATMELMCI=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_EXT4_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_DEBUG_USER=y -CONFIG_XZ_DEC=y -CONFIG_FONTS=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91sam9g45_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91sam9g45_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=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_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9G45=y -CONFIG_MACH_AT91SAM9M10G45EK=y -CONFIG_MACH_AT91SAM9_DT=y -CONFIG_AT91_SLOW_CLOCK=y -CONFIG_AEABI=y -CONFIG_UACCESS_WITH_MEMCPY=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=128M console=ttyS0,115200 initrd=0x71100000,25165824 root=/dev/ram0 rw" -CONFIG_AUTO_ZRELADDR=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -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_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -CONFIG_IPV6_SIT_6RD=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=4 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_MACB=y -CONFIG_DAVICOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_JOYDEV=y -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_QT1070=y -CONFIG_KEYBOARD_QT2160=y -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ATMEL_MXT=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_RESET=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_ATMEL_LCDC=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_BACKLIGHT_PWM=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_LOGO=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_SEQUENCER=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=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_ATMEL_AC97C=y -# CONFIG_SND_SPI is not set -# CONFIG_SND_USB is not set -# CONFIG_USB_HID is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_ACM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_ATMEL_USBA=y -CONFIG_USB_G_MULTI=y -CONFIG_USB_G_MULTI_CDC=y -CONFIG_MMC=y -# CONFIG_MMC_BLOCK_BOUNCE is not set -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -CONFIG_DMADEVICES=y -CONFIG_AT_HDMAC=y -CONFIG_DMATEST=m -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_IIO=y -CONFIG_AT91_ADC=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_EXT4_FS=y -CONFIG_FANOTIFY=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_STRIP_ASM_SYMS=y -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_FTRACE is not set -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -# CONFIG_CRYPTO_HW is not set -CONFIG_FONTS=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91sam9rl_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91sam9rl_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9RL=y -CONFIG_MACH_AT91SAM9RLEK=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw" -CONFIG_AUTO_ZRELADDR=y -CONFIG_NET=y -CONFIG_UNIX=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=4 -CONFIG_BLK_DEV_RAM_SIZE=24576 -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_RESET=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_USB_GADGET=y -CONFIG_USB_ATMEL_USBA=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_IIO=y -CONFIG_AT91_ADC=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_EXT4_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_CRAMFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/at91x40_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/at91x40_defconfig +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -CONFIG_EXPERIMENTAL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_EMBEDDED=y -# CONFIG_HOTPLUG is not set -# CONFIG_ELF_CORE is not set -# CONFIG_FUTEX is not set -# CONFIG_TIMERFD is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_MMU is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91X40=y -CONFIG_MACH_AT91EB01=y -CONFIG_AT91_EARLY_USART0=y -CONFIG_CPU_ARM7TDMI=y -CONFIG_SET_MEM_PARAM=y -CONFIG_DRAM_BASE=0x01000000 -CONFIG_DRAM_SIZE=0x00400000 -CONFIG_FLASH_MEM_BASE=0x01400000 -CONFIG_PROCESSOR_ID=0x14000040 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_BINFMT_FLAT=y -# CONFIG_SUSPEND is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_RAM=y -CONFIG_MTD_ROM=y -CONFIG_BLK_DEV_RAM=y -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_DEVKMEM is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -CONFIG_EXT2_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_ROMFS_FS=y -# CONFIG_ENABLE_MUST_CHECK is not set Index: linux-3.18.13-rt10-r7s4/arch/arm/configs/sama5_defconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/configs/sama5_defconfig +++ linux-3.18.13-rt10-r7s4/arch/arm/configs/sama5_defconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ -# CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_IRQ_DOMAIN_DEBUG=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EMBEDDED=y CONFIG_SLAB=y +CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_LBDAF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:21 @ CONFIG_ARCH_AT91=y CONFIG_SOC_SAM_V7=y CONFIG_SOC_SAMA5D3=y CONFIG_SOC_SAMA5D4=y -CONFIG_MACH_SAMA5_DT=y +CONFIG_AT91_SLOW_CLOCK=y CONFIG_AEABI=y +CONFIG_CMA=y CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ARM_APPENDED_DTB=y CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw" -CONFIG_KEXEC=y CONFIG_AUTO_ZRELADDR=y +CONFIG_CPU_IDLE=y CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_PM_RUNTIME=y CONFIG_PM_DEBUG=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:59 @ CONFIG_IPV6_SIT_6RD=y CONFIG_CAN=y CONFIG_CAN_AT91=y CONFIG_CFG80211=y +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=y CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:67 @ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_DMA_CMA=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:89 @ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set CONFIG_MACB=y # CONFIG_NET_VENDOR_BROADCOM is not set # CONFIG_NET_VENDOR_CIRRUS is not set # CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON 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_QUALCOMM is not set +# CONFIG_NET_VENDOR_SAMSUNG 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_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_MICREL_PHY=y +# CONFIG_USB_NET_DRIVERS is not set CONFIG_LIBERTAS_THINFIRM=m CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_ATMEL_SMARTCONNECT=y +CONFIG_WILC1000=m +CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER=y +CONFIG_USB_ZD1201=m CONFIG_RTL8187=m +CONFIG_ATH_CARDS=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_AR5523=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m CONFIG_RT2X00=m CONFIG_RT2500USB=m CONFIG_RT73USB=m CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_RT55XX=y CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8192CU=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_WL_TI=y +CONFIG_WL1251=m +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_ZD1211RW=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_USB=m +CONFIG_RSI_91X=m +# CONFIG_RSI_DEBUGFS is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:158 @ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_AT91=y CONFIG_I2C_GPIO=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:167 @ CONFIG_SPI_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_AT91_POWEROFF=y +CONFIG_POWER_RESET_AT91_RESET=y # CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_AT91SAM9X_WATCHDOG=y CONFIG_SSB=m +CONFIG_MFD_ATMEL_HLCDC=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_ACT8865=y -CONFIG_FB=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_INPUT_EVDEV is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_VIDEO_ATMEL_ISI=y +CONFIG_SOC_CAMERA_OV2640=y +CONFIG_SOC_CAMERA_OV5642=y +CONFIG_SOC_CAMERA_OV7740=y +CONFIG_SOC_CAMERA_OV9740=y +CONFIG_DRM=y +CONFIG_DRM_I2C_SIL902X=y +CONFIG_DRM_ATMEL_HLCDC=y +CONFIG_DRM_PANEL_SIMPLE=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_BACKLIGHT_PWM=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:219 @ CONFIG_USB_SERIAL_FTDI_SIO=y CONFIG_USB_SERIAL_PL2303=y CONFIG_USB_GADGET=y CONFIG_USB_ATMEL_USBA=y -CONFIG_USB_G_SERIAL=y +CONFIG_USB_G_SERIAL=m CONFIG_MMC=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ATMELMCI=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:233 @ CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT91RM9200=y CONFIG_DMADEVICES=y +CONFIG_AT_XDMAC=y +CONFIG_DMATEST=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_IIO=y CONFIG_AT91_ADC=y CONFIG_PWM=y CONFIG_PWM_ATMEL=y +CONFIG_PWM_ATMEL_HLCDC_PWM=y +CONFIG_PWM_ATMEL_TCB=y +CONFIG_RESET_CONTROLLER=y CONFIG_EXT4_FS=y CONFIG_FANOTIFY=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_ADVANCED_COMPR=y CONFIG_NFS_FS=y @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:258 @ CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_SCHED_DEBUG is not set # CONFIG_FTRACE is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m Index: linux-3.18.13-rt10-r7s4/arch/arm/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/Kconfig +++ linux-3.18.13-rt10-r7s4/arch/arm/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:379 @ config ARCH_AT91 select IRQ_DOMAIN select NEED_MACH_IO_H if PCCARD select PINCTRL - select PINCTRL_AT91 if USE_OF + select PINCTRL_AT91 + select USE_OF help This enables support for systems based on Atmel - AT91RM9200 and AT91SAM9* processors. + AT91RM9200, AT91SAM9 and SAMA5 processors. config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91_aic.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91_aic.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/at91_aic.h - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * - * Advanced Interrupt Controller (AIC) - System peripherals registers. - * Based on AT91RM9200 datasheet revision E. - * - * 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. - */ - -#ifndef AT91_AIC_H -#define AT91_AIC_H - -#ifndef __ASSEMBLY__ -extern void __iomem *at91_aic_base; - -#define at91_aic_read(field) \ - __raw_readl(at91_aic_base + field) - -#define at91_aic_write(field, value) \ - __raw_writel(value, at91_aic_base + field) -#else -.extern at91_aic_base -#endif - -/* Number of irq lines managed by AIC */ -#define NR_AIC_IRQS 32 -#define NR_AIC5_IRQS 128 - -#define AT91_AIC5_SSR 0x0 /* Source Select Register [AIC5] */ -#define AT91_AIC5_INTSEL_MSK (0x7f << 0) /* Interrupt Line Selection Mask */ - -#define AT91_AIC_IRQ_MIN_PRIORITY 0 -#define AT91_AIC_IRQ_MAX_PRIORITY 7 - -#define AT91_AIC_SMR(n) ((n) * 4) /* Source Mode Registers 0-31 */ -#define AT91_AIC5_SMR 0x4 /* Source Mode Register [AIC5] */ -#define AT91_AIC_PRIOR (7 << 0) /* Priority Level */ -#define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */ -#define AT91_AIC_SRCTYPE_LOW (0 << 5) -#define AT91_AIC_SRCTYPE_FALLING (1 << 5) -#define AT91_AIC_SRCTYPE_HIGH (2 << 5) -#define AT91_AIC_SRCTYPE_RISING (3 << 5) - -#define AT91_AIC_SVR(n) (0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ -#define AT91_AIC5_SVR 0x8 /* Source Vector Register [AIC5] */ -#define AT91_AIC_IVR 0x100 /* Interrupt Vector Register */ -#define AT91_AIC5_IVR 0x10 /* Interrupt Vector Register [AIC5] */ -#define AT91_AIC_FVR 0x104 /* Fast Interrupt Vector Register */ -#define AT91_AIC5_FVR 0x14 /* Fast Interrupt Vector Register [AIC5] */ -#define AT91_AIC_ISR 0x108 /* Interrupt Status Register */ -#define AT91_AIC5_ISR 0x18 /* Interrupt Status Register [AIC5] */ -#define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */ - -#define AT91_AIC_IPR 0x10c /* Interrupt Pending Register */ -#define AT91_AIC5_IPR0 0x20 /* Interrupt Pending Register 0 [AIC5] */ -#define AT91_AIC5_IPR1 0x24 /* Interrupt Pending Register 1 [AIC5] */ -#define AT91_AIC5_IPR2 0x28 /* Interrupt Pending Register 2 [AIC5] */ -#define AT91_AIC5_IPR3 0x2c /* Interrupt Pending Register 3 [AIC5] */ -#define AT91_AIC_IMR 0x110 /* Interrupt Mask Register */ -#define AT91_AIC5_IMR 0x30 /* Interrupt Mask Register [AIC5] */ -#define AT91_AIC_CISR 0x114 /* Core Interrupt Status Register */ -#define AT91_AIC5_CISR 0x34 /* Core Interrupt Status Register [AIC5] */ -#define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */ -#define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */ - -#define AT91_AIC_IECR 0x120 /* Interrupt Enable Command Register */ -#define AT91_AIC5_IECR 0x40 /* Interrupt Enable Command Register [AIC5] */ -#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */ -#define AT91_AIC5_IDCR 0x44 /* Interrupt Disable Command Register [AIC5] */ -#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */ -#define AT91_AIC5_ICCR 0x48 /* Interrupt Clear Command Register [AIC5] */ -#define AT91_AIC_ISCR 0x12c /* Interrupt Set Command Register */ -#define AT91_AIC5_ISCR 0x4c /* Interrupt Set Command Register [AIC5] */ -#define AT91_AIC_EOICR 0x130 /* End of Interrupt Command Register */ -#define AT91_AIC5_EOICR 0x38 /* End of Interrupt Command Register [AIC5] */ -#define AT91_AIC_SPU 0x134 /* Spurious Interrupt Vector Register */ -#define AT91_AIC5_SPU 0x3c /* Spurious Interrupt Vector Register [AIC5] */ -#define AT91_AIC_DCR 0x138 /* Debug Control Register */ -#define AT91_AIC5_DCR 0x6c /* Debug Control Register [AIC5] */ -#define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */ -#define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */ - -#define AT91_AIC_FFER 0x140 /* Fast Forcing Enable Register [SAM9 only] */ -#define AT91_AIC5_FFER 0x50 /* Fast Forcing Enable Register [AIC5] */ -#define AT91_AIC_FFDR 0x144 /* Fast Forcing Disable Register [SAM9 only] */ -#define AT91_AIC5_FFDR 0x54 /* Fast Forcing Disable Register [AIC5] */ -#define AT91_AIC_FFSR 0x148 /* Fast Forcing Status Register [SAM9 only] */ -#define AT91_AIC5_FFSR 0x58 /* Fast Forcing Status Register [AIC5] */ - -void at91_aic_handle_irq(struct pt_regs *regs); -void at91_aic5_handle_irq(struct pt_regs *regs); - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91rm9200.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91rm9200.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91rm9200.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:14 @ */ #include <linux/module.h> -#include <linux/reboot.h> #include <linux/clk/at91_pmc.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/system_misc.h> -#include <mach/at91rm9200.h> #include <mach/at91_st.h> -#include <mach/cpu.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk udc_clk = { - .name = "udc_clk", - .pmc_mask = 1 << AT91RM9200_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91RM9200_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ether_clk = { - .name = "ether_clk", - .pmc_mask = 1 << AT91RM9200_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91RM9200_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91RM9200_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91RM9200_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91RM9200_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91RM9200_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91RM9200_ID_US3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi_clk = { - .name = "spi_clk", - .pmc_mask = 1 << AT91RM9200_ID_SPI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioD_clk = { - .name = "pioD_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc2_clk = { - .name = "ssc2_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc0_clk = { - .name = "tc0_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc1_clk = { - .name = "tc1_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc2_clk = { - .name = "tc2_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc3_clk = { - .name = "tc3_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc4_clk = { - .name = "tc4_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc5_clk = { - .name = "tc5_clk", - .pmc_mask = 1 << AT91RM9200_ID_TC5, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioD_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc_clk, - &udc_clk, - &twi_clk, - &spi_clk, - &ssc0_clk, - &ssc1_clk, - &ssc2_clk, - &tc0_clk, - &tc1_clk, - &tc2_clk, - &tc3_clk, - &tc4_clk, - &tc5_clk, - &ohci_clk, - ðer_clk, - // irq0 .. irq6 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), - CLKDEV_CON_DEV_ID("pclk", "fffd0000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "fffd4000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "fffd8000.ssc", &ssc2_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioC_clk), - CLKDEV_CON_ID("pioD", &pioD_clk), - /* usart lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fffc0000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "fffc4000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fffc8000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "fffcc000.serial", &usart3_clk), - /* tc lookup table for DT entries */ - CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffa4000.timer", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa4000.timer", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa4000.timer", &tc5_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffb4000.mmc", &mmc_clk), - CLKDEV_CON_DEV_ID("emac_clk", "fffbc000.ethernet", ðer_clk), - CLKDEV_CON_DEV_ID(NULL, "fffb8000.i2c", &twi_clk), - CLKDEV_CON_DEV_ID("hclk", "300000.ohci", &ohci_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91rm9200_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} -#else -#define at91rm9200_register_clocks NULL -#endif - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91rm9200_gpio[] __initdata = { - { - .id = AT91RM9200_ID_PIOA, - .regbase = AT91RM9200_BASE_PIOA, - }, { - .id = AT91RM9200_ID_PIOB, - .regbase = AT91RM9200_BASE_PIOB, - }, { - .id = AT91RM9200_ID_PIOC, - .regbase = AT91RM9200_BASE_PIOC, - }, { - .id = AT91RM9200_ID_PIOD, - .regbase = AT91RM9200_BASE_PIOD, - } -}; static void at91rm9200_idle(void) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:45 @ static void at91rm9200_restart(enum rebo /* -------------------------------------------------------------------- * AT91RM9200 processor initialization * -------------------------------------------------------------------- */ -static void __init at91rm9200_map_io(void) -{ - /* Map peripherals */ - at91_init_sram(0, AT91RM9200_SRAM_BASE, AT91RM9200_SRAM_SIZE); -} - -static void __init at91rm9200_ioremap_registers(void) -{ - at91rm9200_ioremap_st(AT91RM9200_BASE_ST); - at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256); - at91_pm_set_standby(at91rm9200_standby); -} static void __init at91rm9200_initialize(void) { arm_pm_idle = at91rm9200_idle; arm_pm_restart = at91rm9200_restart; - - /* Initialize GPIO subsystem */ - at91_gpio_init(at91rm9200_gpio, - cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP); } -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 1, /* Parallel IO Controller D */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 4, /* Serial Synchronous Controller 2 */ - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 2, /* USB Host port */ - 3, /* Ethernet MAC */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ - 0, /* Advanced Interrupt Controller (IRQ2) */ - 0, /* Advanced Interrupt Controller (IRQ3) */ - 0, /* Advanced Interrupt Controller (IRQ4) */ - 0, /* Advanced Interrupt Controller (IRQ5) */ - 0 /* Advanced Interrupt Controller (IRQ6) */ -}; - AT91_SOC_START(at91rm9200) - .map_io = at91rm9200_map_io, - .default_irq_priority = at91rm9200_default_irq_priority, - .extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) - | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) - | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) - | (1 << AT91RM9200_ID_IRQ6), - .ioremap_registers = at91rm9200_ioremap_registers, - .register_clocks = at91rm9200_register_clocks, .init = at91rm9200_initialize, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91rm9200_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91rm9200_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91rm9200_devices.c - * - * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> - * Copyright (C) 2005 David Brownell - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <mach/at91rm9200.h> -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> -#include <mach/hardware.h> - -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91RM9200_UHP_BASE, - .end = AT91RM9200_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_UHP, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91rm9200_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE) -static struct at91_udc_data udc_data; - -static struct resource udc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_UDP, - .end = AT91RM9200_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_UDP, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = udc_resources, - .num_resources = ARRAY_SIZE(udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - if (gpio_is_valid(data->pullup_pin)) - at91_set_gpio_output(data->pullup_pin, 0); - - udc_data = *data; - platform_device_register(&at91rm9200_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91RM9200_BASE_EMAC, - .end = AT91RM9200_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_EMAC, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_eth_device = { - .name = "at91_ether", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ - at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ - at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ - at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ - } - - eth_data = *data; - platform_device_register(&at91rm9200_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Compact Flash / PCMCIA - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) -static struct at91_cf_data cf_data; - -#define CF_BASE AT91_CHIPSELECT_4 - -static struct resource cf_resources[] = { - [0] = { - .start = CF_BASE, - /* ties up CS4, CS5 and CS6 */ - .end = CF_BASE + (0x30000000 - 1), - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - }, -}; - -static struct platform_device at91rm9200_cf_device = { - .name = "at91_cf", - .id = -1, - .dev = { - .platform_data = &cf_data, - }, - .resource = cf_resources, - .num_resources = ARRAY_SIZE(cf_resources), -}; - -void __init at91_add_device_cf(struct at91_cf_data *data) -{ - unsigned int csa; - - if (!data) - return; - - data->chipselect = 4; /* can only use EBI ChipSelect 4 */ - - /* CF takes over CS4, CS5, CS6 */ - csa = at91_ramc_read(0, AT91_EBI_CSA); - at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); - - /* - * Static memory controller timing adjustments. - * REVISIT: these timings are in terms of MCK cycles, so - * when MCK changes (cpufreq etc) so must these values... - */ - at91_ramc_write(0, AT91_SMC_CSR(4), - AT91_SMC_ACSS_STD - | AT91_SMC_DBW_16 - | AT91_SMC_BAT - | AT91_SMC_WSEN - | AT91_SMC_NWS_(32) /* wait states */ - | AT91_SMC_RWSETUP_(6) /* setup time */ - | AT91_SMC_RWHOLD_(4) /* hold time */ - ); - - /* input/irq */ - if (gpio_is_valid(data->irq_pin)) { - at91_set_gpio_input(data->irq_pin, 1); - at91_set_deglitch(data->irq_pin, 1); - } - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - - /* outputs, initially off */ - if (gpio_is_valid(data->vcc_pin)) - at91_set_gpio_output(data->vcc_pin, 0); - at91_set_gpio_output(data->rst_pin, 0); - - /* force poweron defaults for these pins ... */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ - at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ - - /* nWAIT is _not_ a default setting */ - at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ - - cf_data = *data; - platform_device_register(&at91rm9200_cf_device); -} -#else -void __init at91_add_device_cf(struct at91_cf_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc_data; - -static struct resource mmc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_MCI, - .end = AT91RM9200_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_MCI, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_mmc_device = { - .name = "atmel_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc_data, - }, - .resource = mmc_resources, - .num_resources = ARRAY_SIZE(mmc_resources), -}; - -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - unsigned int i; - unsigned int slot_count = 0; - - if (!data) - return; - - for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { - - if (!data->slot[i].bus_width) - continue; - - /* input/irq */ - if (gpio_is_valid(data->slot[i].detect_pin)) { - at91_set_gpio_input(data->slot[i].detect_pin, 1); - at91_set_deglitch(data->slot[i].detect_pin, 1); - } - if (gpio_is_valid(data->slot[i].wp_pin)) - at91_set_gpio_input(data->slot[i].wp_pin, 1); - - switch (i) { - case 0: /* slot A */ - /* CMD */ - at91_set_A_periph(AT91_PIN_PA28, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA29, 1); - if (data->slot[i].bus_width == 4) { - at91_set_B_periph(AT91_PIN_PB3, 1); - at91_set_B_periph(AT91_PIN_PB4, 1); - at91_set_B_periph(AT91_PIN_PB5, 1); - } - slot_count++; - break; - case 1: /* slot B */ - /* CMD */ - at91_set_B_periph(AT91_PIN_PA8, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA9, 1); - if (data->slot[i].bus_width == 4) { - at91_set_B_periph(AT91_PIN_PA10, 1); - at91_set_B_periph(AT91_PIN_PA11, 1); - at91_set_B_periph(AT91_PIN_PA12, 1); - } - slot_count++; - break; - default: - printk(KERN_ERR - "AT91: SD/MMC slot %d not available\n", i); - break; - } - if (slot_count) { - /* CLK */ - at91_set_A_periph(AT91_PIN_PA27, 0); - - mmc_data = *data; - platform_device_register(&at91rm9200_mmc_device); - } - } - -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91rm9200_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned int csa; - - if (!data) - return; - - /* enable the address range of CS3 */ - csa = at91_ramc_read(0, AT91_EBI_CSA); - at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); - - /* set the bus interface characteristics */ - at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN - | AT91_SMC_NWS_(5) - | AT91_SMC_TDF_(1) - | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ - | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ - ); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ - - nand_data = *data; - platform_device_register(&at91rm9200_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PA25, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA26, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91rm9200_twi_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA25, 1); - - at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA26, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91rm9200_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91RM9200_BASE_TWI, - .end = AT91RM9200_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TWI, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_twi_device = { - .name = "i2c-at91rm9200", - .id = 0, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA25, 1); - - at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA26, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91rm9200_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SPI, - .end = AT91RM9200_BASE_SPI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_SPI, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_spi_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi_resources, - .num_resources = ARRAY_SIZE(spi_resources), -}; - -static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - - at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ - at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ - - /* Enable SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else - cs_pin = spi_standard_cs[devices[i].chip_select]; - - if (devices[i].chip_select == 0) /* for CS0 errata */ - at91_set_A_periph(cs_pin, 0); - else - at91_set_gpio_output(cs_pin, 1); - - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - platform_device_register(&at91rm9200_spi_device); -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter blocks - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb0_resources[] = { - [0] = { - .start = AT91RM9200_BASE_TCB0, - .end = AT91RM9200_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC0, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC0, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC1, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC1, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC2, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_tcb0_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb0_resources, - .num_resources = ARRAY_SIZE(tcb0_resources), -}; - -static struct resource tcb1_resources[] = { - [0] = { - .start = AT91RM9200_BASE_TCB1, - .end = AT91RM9200_BASE_TCB1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC3, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC3, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC4, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC4, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_TC5, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_TC5, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_tcb1_device = { - .name = "atmel_tcb", - .id = 1, - .resource = tcb1_resources, - .num_resources = ARRAY_SIZE(tcb1_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91rm9200_tcb0_device); - platform_device_register(&at91rm9200_tcb1_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) -static struct resource rtc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_RTC, - .end = AT91RM9200_BASE_RTC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_rtc_device = { - .name = "at91_rtc", - .id = -1, - .resource = rtc_resources, - .num_resources = ARRAY_SIZE(rtc_resources), -}; - -static void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91rm9200_rtc_device); -} -#else -static void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) -static struct platform_device at91rm9200_wdt_device = { - .name = "at91_wdt", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91rm9200_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SSC0, - .end = AT91RM9200_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_SSC0, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_ssc0_device = { - .name = "at91rm9200_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB0, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB1, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB2, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB3, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB4, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB5, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SSC1, - .end = AT91RM9200_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_SSC1, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_ssc1_device = { - .name = "at91rm9200_ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB6, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB7, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB8, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB9, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB10, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB11, 1); -} - -static u64 ssc2_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc2_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SSC2, - .end = AT91RM9200_BASE_SSC2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_SSC2, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_SSC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_ssc2_device = { - .name = "at91rm9200_ssc", - .id = 2, - .dev = { - .dma_mask = &ssc2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc2_resources, - .num_resources = ARRAY_SIZE(ssc2_resources), -}; - -static inline void configure_ssc2_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB12, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB13, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB14, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB15, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB16, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB17, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91RM9200_ID_SSC0: - pdev = &at91rm9200_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91RM9200_ID_SSC1: - pdev = &at91rm9200_ssc1_device; - configure_ssc1_pins(pins); - break; - case AT91RM9200_ID_SSC2: - pdev = &at91rm9200_ssc2_device; - configure_ssc2_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91RM9200_BASE_DBGU, - .end = AT91RM9200_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91rm9200_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US0, - .end = AT91RM9200_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_US0, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct gpiod_lookup_table uart0_gpios_table = { - .dev_id = "atmel_usart", - .table = { - GPIO_LOOKUP("pioA", 21, "rts", GPIO_ACTIVE_LOW), - { }, - }, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91rm9200_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ - - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ - - if (pins & ATMEL_UART_RTS) { - /* - * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. - * We need to drive the pin manually. The serial driver will driver - * this to high when initializing. - */ - gpiod_add_lookup_table(&uart0_gpios_table); - } -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US1, - .end = AT91RM9200_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_US1, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91rm9200_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RI) - at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ - if (pins & ATMEL_UART_DTR) - at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ - if (pins & ATMEL_UART_DCD) - at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ - if (pins & ATMEL_UART_DSR) - at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US2, - .end = AT91RM9200_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_US2, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91rm9200_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ - - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */ - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US3, - .end = AT91RM9200_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91RM9200_ID_US3, - .end = NR_IRQS_LEGACY + AT91RM9200_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart3_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91rm9200_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .dma_mask = &uart3_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart3_data, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(unsigned pins) -{ - at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ - - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */ - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91rm9200_dbgu_device; - configure_dbgu_pins(); - break; - case AT91RM9200_ID_US0: - pdev = &at91rm9200_uart0_device; - configure_usart0_pins(pins); - break; - case AT91RM9200_ID_US1: - pdev = &at91rm9200_uart1_device; - configure_usart1_pins(pins); - break; - case AT91RM9200_ID_US2: - pdev = &at91rm9200_uart2_device; - configure_usart2_pins(pins); - break; - case AT91RM9200_ID_US3: - pdev = &at91rm9200_uart3_device; - configure_usart3_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtc(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91rm9200_time.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91rm9200_time.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91rm9200_time.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:186 @ static struct clock_event_device clkevt void __iomem *at91_st_base; EXPORT_SYMBOL_GPL(at91_st_base); -#ifdef CONFIG_OF static struct of_device_id at91rm9200_st_timer_ids[] = { { .compatible = "atmel,at91rm9200-st" }, { /* sentinel */ } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:221 @ node_err: err: return -EINVAL; } -#else -static int __init of_at91rm9200_st_init(void) -{ - return -EINVAL; -} -#endif - -void __init at91rm9200_ioremap_st(u32 addr) -{ -#ifdef CONFIG_OF - struct device_node *np; - - np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); - if (np) { - of_node_put(np); - return; - } -#endif - at91_st_base = ioremap(addr, 256); - if (!at91_st_base) - panic("Impossible to ioremap ST\n"); -} /* * ST (system timer) module supports both clockevents and clocksource. Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9260.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9260.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9260.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * */ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk/at91_pmc.h> - -#include <asm/proc-fns.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/system_misc.h> #include <mach/cpu.h> #include <mach/at91_dbgu.h> -#include <mach/at91sam9260.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91SAM9260_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91SAM9260_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91SAM9260_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91SAM9260_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk adc_op_clk = { - .name = "adc_op_clk", - .type = CLK_TYPE_PERIPHERAL, - .rate_hz = 5000000, -}; - -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91SAM9260_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udc_clk = { - .name = "udc_clk", - .pmc_mask = 1 << AT91SAM9260_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9260_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9260_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc_clk = { - .name = "ssc_clk", - .pmc_mask = 1 << AT91SAM9260_ID_SSC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc0_clk = { - .name = "tc0_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc1_clk = { - .name = "tc1_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc2_clk = { - .name = "tc2_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91SAM9260_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91SAM9260_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91SAM9260_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart4_clk = { - .name = "usart4_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart5_clk = { - .name = "usart5_clk", - .pmc_mask = 1 << AT91SAM9260_ID_US5, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc3_clk = { - .name = "tc3_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc4_clk = { - .name = "tc4_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc5_clk = { - .name = "tc5_clk", - .pmc_mask = 1 << AT91SAM9260_ID_TC5, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &adc_clk, - &adc_op_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc_clk, - &udc_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc_clk, - &tc0_clk, - &tc1_clk, - &tc2_clk, - &ohci_clk, - &macb_clk, - &isi_clk, - &usart3_clk, - &usart4_clk, - &usart5_clk, - &tc3_clk, - &tc4_clk, - &tc5_clk, - // irq0 .. irq2 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc_clk), - CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), - /* more usart lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "fffb4000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fffb8000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), - CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), - CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), - CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk), - /* more tc lookup table for DT entries */ - CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), - CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk), -}; - -/* - * The two programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static void __init at91sam9260_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); -} -#else -#define at91sam9260_register_clocks NULL -#endif - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91sam9260_gpio[] __initdata = { - { - .id = AT91SAM9260_ID_PIOA, - .regbase = AT91SAM9260_BASE_PIOA, - }, { - .id = AT91SAM9260_ID_PIOB, - .regbase = AT91SAM9260_BASE_PIOB, - }, { - .id = AT91SAM9260_ID_PIOC, - .regbase = AT91SAM9260_BASE_PIOC, - } -}; /* -------------------------------------------------------------------- * AT91SAM9260 processor initialization * -------------------------------------------------------------------- */ - -static void __init at91sam9xe_map_io(void) -{ - unsigned long sram_size; - - switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) { - case AT91_CIDR_SRAMSIZ_32K: - sram_size = 2 * SZ_16K; - break; - case AT91_CIDR_SRAMSIZ_16K: - default: - sram_size = SZ_16K; - } - - at91_init_sram(0, AT91SAM9XE_SRAM_BASE, sram_size); -} - -static void __init at91sam9260_map_io(void) -{ - if (cpu_is_at91sam9xe()) - at91sam9xe_map_io(); - else if (cpu_is_at91sam9g20()) - at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE); - else - at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE); -} - -static void __init at91sam9260_ioremap_registers(void) -{ - at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); - at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); - at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); - at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX); - at91_pm_set_standby(at91sam9_sdram_standby); -} - static void __init at91sam9260_initialize(void) { arm_pm_idle = at91sam9_idle; at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); - - /* Register GPIO subsystem */ - at91_gpio_init(at91sam9260_gpio, 3); -} - -static struct resource rstc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_RSTC, - .end = AT91SAM9260_BASE_RSTC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9260_BASE_SDRAMC, - .end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device rstc_device = { - .name = "at91-sam9260-reset", - .resource = rstc_resources, - .num_resources = ARRAY_SIZE(rstc_resources), -}; - -static struct resource shdwc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_SHDWC, - .end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device shdwc_device = { - .name = "at91-poweroff", - .resource = shdwc_resources, - .num_resources = ARRAY_SIZE(shdwc_resources), -}; - -static void __init at91sam9260_register_devices(void) -{ - platform_device_register(&rstc_device); - platform_device_register(&shdwc_device); -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, /* Analog-to-Digital Converter */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* Serial Synchronous Controller */ - 0, - 0, - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 5, /* USART 3 */ - 5, /* USART 4 */ - 5, /* USART 5 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ -}; - -static void __init at91sam9260_init_time(void) -{ - at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); } AT91_SOC_START(at91sam9260) - .map_io = at91sam9260_map_io, - .default_irq_priority = at91sam9260_default_irq_priority, - .extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) - | (1 << AT91SAM9260_ID_IRQ2), - .ioremap_registers = at91sam9260_ioremap_registers, - .register_clocks = at91sam9260_register_clocks, - .register_devices = at91sam9260_register_devices, .init = at91sam9260_initialize, - .init_time = at91sam9260_init_time, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9260_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9260_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91sam9260_devices.c - * - * Copyright (C) 2006 Atmel - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <linux/platform_data/at91_adc.h> - -#include <mach/cpu.h> -#include <mach/at91sam9260.h> -#include <mach/at91sam9260_matrix.h> -#include <mach/at91_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "board.h" -#include "generic.h" -#include "gpio.h" - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91SAM9260_UHP_BASE, - .end = AT91SAM9260_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_UHP, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE) -static struct at91_udc_data udc_data; - -static struct resource udc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_UDP, - .end = AT91SAM9260_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_UDP, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = udc_resources, - .num_resources = ARRAY_SIZE(udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - - /* Pullup pin is handled internally by USB device peripheral */ - - udc_data = *data; - platform_device_register(&at91_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_EMAC, - .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_EMAC, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_eth_device = { - .name = "macb", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */ - at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ - at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */ - } - - eth_data = *data; - platform_device_register(&at91sam9260_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD Slot for Atmel MCI Driver - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc_data; - -static struct resource mmc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_MCI, - .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_MCI, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_mmc_device = { - .name = "atmel_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc_data, - }, - .resource = mmc_resources, - .num_resources = ARRAY_SIZE(mmc_resources), -}; - -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - unsigned int i; - unsigned int slot_count = 0; - - if (!data) - return; - - for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { - if (data->slot[i].bus_width) { - /* input/irq */ - if (gpio_is_valid(data->slot[i].detect_pin)) { - at91_set_gpio_input(data->slot[i].detect_pin, 1); - at91_set_deglitch(data->slot[i].detect_pin, 1); - } - if (gpio_is_valid(data->slot[i].wp_pin)) - at91_set_gpio_input(data->slot[i].wp_pin, 1); - - switch (i) { - case 0: - /* CMD */ - at91_set_A_periph(AT91_PIN_PA7, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA6, 1); - if (data->slot[i].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA9, 1); - at91_set_A_periph(AT91_PIN_PA10, 1); - at91_set_A_periph(AT91_PIN_PA11, 1); - } - slot_count++; - break; - case 1: - /* CMD */ - at91_set_B_periph(AT91_PIN_PA1, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA0, 1); - if (data->slot[i].bus_width == 4) { - at91_set_B_periph(AT91_PIN_PA5, 1); - at91_set_B_periph(AT91_PIN_PA4, 1); - at91_set_B_periph(AT91_PIN_PA3, 1); - } - slot_count++; - break; - default: - printk(KERN_ERR - "AT91: SD/MMC slot %d not available\n", i); - break; - } - } - } - - if (slot_count) { - /* CLK */ - at91_set_A_periph(AT91_PIN_PA8, 0); - - mmc_data = *data; - platform_device_register(&at91sam9260_mmc_device); - } -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9260_BASE_ECC, - .end = AT91SAM9260_BASE_ECC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9260_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - nand_data = *data; - platform_device_register(&at91sam9260_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ - -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PA23, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA24, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91sam9260_twi_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA23, 1); - - at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA24, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9260_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_TWI, - .end = AT91SAM9260_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TWI, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_twi_device = { - .id = 0, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* IP version is not the same on 9260 and g20 */ - if (cpu_is_at91sam9g20()) { - at91sam9260_twi_device.name = "i2c-at91sam9g20"; - } else { - at91sam9260_twi_device.name = "i2c-at91sam9260"; - } - - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA23, 1); - - at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA24, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9260_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_SPI0, - .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_SPI0, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_SPI1, - .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_SPI1, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (!gpio_is_valid(cs_pin)) - continue; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ - at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ - - platform_device_register(&at91sam9260_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ - - platform_device_register(&at91sam9260_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter blocks - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb0_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_TCB0, - .end = AT91SAM9260_BASE_TCB0 + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC0, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC0, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC1, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC1, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC2, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_tcb0_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb0_resources, - .num_resources = ARRAY_SIZE(tcb0_resources), -}; - -static struct resource tcb1_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_TCB1, - .end = AT91SAM9260_BASE_TCB1 + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC3, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC3, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC4, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC4, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_TC5, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_TC5, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_tcb1_device = { - .name = "atmel_tcb", - .id = 1, - .resource = tcb1_resources, - .num_resources = ARRAY_SIZE(tcb1_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91sam9260_tcb0_device); - platform_device_register(&at91sam9260_tcb1_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91SAM9260_BASE_RTT, - .end = AT91SAM9260_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, -}; - - -#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) -static void __init at91_add_device_rtt_rtc(void) -{ - at91sam9260_rtt_device.name = "rtc-at91sam9"; - /* - * The second resource is needed: - * GPBR will serve as the storage for RTC time offset - */ - at91sam9260_rtt_device.num_resources = 3; - rtt_resources[1].start = AT91SAM9260_BASE_GPBR + - 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; - rtt_resources[1].end = rtt_resources[1].start + 3; - rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; - rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; -} -#else -static void __init at91_add_device_rtt_rtc(void) -{ - /* Only one resource is needed: RTT not used as RTC */ - at91sam9260_rtt_device.num_resources = 1; -} -#endif - -static void __init at91_add_device_rtt(void) -{ - at91_add_device_rtt_rtc(); - platform_device_register(&at91sam9260_rtt_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91SAM9260_BASE_WDT, - .end = AT91SAM9260_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9260_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91sam9260_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_SSC, - .end = AT91SAM9260_BASE_SSC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_SSC, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_SSC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9260_ssc_device = { - .name = "at91rm9200_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc_resources, - .num_resources = ARRAY_SIZE(ssc_resources), -}; - -static inline void configure_ssc_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB17, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB16, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB18, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB19, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB20, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB21, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91SAM9260_ID_SSC: - pdev = &at91sam9260_ssc_device; - configure_ssc_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_DBGU, - .end = AT91SAM9260_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US0, - .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US0, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ - if (pins & ATMEL_UART_DTR) - at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ - if (pins & ATMEL_UART_DSR) - at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ - if (pins & ATMEL_UART_DCD) - at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ - if (pins & ATMEL_UART_RI) - at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US1, - .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US1, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US2, - .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US2, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US3, - .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US3, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart3_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .dma_mask = &uart3_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart3_data, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ - at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */ -} - -static struct resource uart4_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US4, - .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US4, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US4, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart4_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart4_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart4_device = { - .name = "atmel_usart", - .id = 5, - .dev = { - .dma_mask = &uart4_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart4_data, - }, - .resource = uart4_resources, - .num_resources = ARRAY_SIZE(uart4_resources), -}; - -static inline void configure_usart4_pins(void) -{ - at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ - at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ -} - -static struct resource uart5_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_US5, - .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_US5, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_US5, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart5_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart5_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9260_uart5_device = { - .name = "atmel_usart", - .id = 6, - .dev = { - .dma_mask = &uart5_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart5_data, - }, - .resource = uart5_resources, - .num_resources = ARRAY_SIZE(uart5_resources), -}; - -static inline void configure_usart5_pins(void) -{ - at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ - at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91sam9260_dbgu_device; - configure_dbgu_pins(); - break; - case AT91SAM9260_ID_US0: - pdev = &at91sam9260_uart0_device; - configure_usart0_pins(pins); - break; - case AT91SAM9260_ID_US1: - pdev = &at91sam9260_uart1_device; - configure_usart1_pins(pins); - break; - case AT91SAM9260_ID_US2: - pdev = &at91sam9260_uart2_device; - configure_usart2_pins(pins); - break; - case AT91SAM9260_ID_US3: - pdev = &at91sam9260_uart3_device; - configure_usart3_pins(pins); - break; - case AT91SAM9260_ID_US4: - pdev = &at91sam9260_uart4_device; - configure_usart4_pins(); - break; - case AT91SAM9260_ID_US5: - pdev = &at91sam9260_uart5_device; - configure_usart5_pins(); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - -/* -------------------------------------------------------------------- - * CF/IDE - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ - defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) - -static struct at91_cf_data cf0_data; - -static struct resource cf0_resources[] = { - [0] = { - .start = AT91_CHIPSELECT_4, - .end = AT91_CHIPSELECT_4 + SZ_256M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device cf0_device = { - .id = 0, - .dev = { - .platform_data = &cf0_data, - }, - .resource = cf0_resources, - .num_resources = ARRAY_SIZE(cf0_resources), -}; - -static struct at91_cf_data cf1_data; - -static struct resource cf1_resources[] = { - [0] = { - .start = AT91_CHIPSELECT_5, - .end = AT91_CHIPSELECT_5 + SZ_256M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device cf1_device = { - .id = 1, - .dev = { - .platform_data = &cf1_data, - }, - .resource = cf1_resources, - .num_resources = ARRAY_SIZE(cf1_resources), -}; - -void __init at91_add_device_cf(struct at91_cf_data *data) -{ - struct platform_device *pdev; - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - - switch (data->chipselect) { - case 4: - at91_set_multi_drive(AT91_PIN_PC8, 0); - at91_set_A_periph(AT91_PIN_PC8, 0); - csa |= AT91_MATRIX_CS4A_SMC_CF1; - cf0_data = *data; - pdev = &cf0_device; - break; - case 5: - at91_set_multi_drive(AT91_PIN_PC9, 0); - at91_set_A_periph(AT91_PIN_PC9, 0); - csa |= AT91_MATRIX_CS5A_SMC_CF2; - cf1_data = *data; - pdev = &cf1_device; - break; - default: - printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", - data->chipselect); - return; - } - - at91_matrix_write(AT91_MATRIX_EBICSA, csa); - - if (gpio_is_valid(data->rst_pin)) { - at91_set_multi_drive(data->rst_pin, 0); - at91_set_gpio_output(data->rst_pin, 1); - } - - if (gpio_is_valid(data->irq_pin)) { - at91_set_gpio_input(data->irq_pin, 0); - at91_set_deglitch(data->irq_pin, 1); - } - - if (gpio_is_valid(data->det_pin)) { - at91_set_gpio_input(data->det_pin, 0); - at91_set_deglitch(data->det_pin, 1); - } - - at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */ - at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */ - at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */ - - if (IS_ENABLED(CONFIG_PATA_AT91) && (data->flags & AT91_CF_TRUE_IDE)) - pdev->name = "pata_at91"; - else - pdev->name = "at91_cf"; - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_cf(struct at91_cf_data * data) {} -#endif - -/* -------------------------------------------------------------------- - * ADCs - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_AT91_ADC) -static struct at91_adc_data adc_data; - -static struct resource adc_resources[] = { - [0] = { - .start = AT91SAM9260_BASE_ADC, - .end = AT91SAM9260_BASE_ADC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9260_ID_ADC, - .end = NR_IRQS_LEGACY + AT91SAM9260_ID_ADC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_adc_device = { - .name = "at91sam9260-adc", - .id = -1, - .dev = { - .platform_data = &adc_data, - }, - .resource = adc_resources, - .num_resources = ARRAY_SIZE(adc_resources), -}; - -static struct at91_adc_trigger at91_adc_triggers[] = { - [0] = { - .name = "timer-counter-0", - .value = 0x1, - }, - [1] = { - .name = "timer-counter-1", - .value = 0x3, - }, - [2] = { - .name = "timer-counter-2", - .value = 0x5, - }, - [3] = { - .name = "external", - .value = 0xd, - .is_external = true, - }, -}; - -void __init at91_add_device_adc(struct at91_adc_data *data) -{ - if (!data) - return; - - if (test_bit(0, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PC0, 0); - if (test_bit(1, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PC1, 0); - if (test_bit(2, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PC2, 0); - if (test_bit(3, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PC3, 0); - - if (data->use_external_triggers) - at91_set_A_periph(AT91_PIN_PA22, 0); - - data->startup_time = 10; - data->trigger_number = 4; - data->trigger_list = at91_adc_triggers; - - adc_data = *data; - platform_device_register(&at91_adc_device); -} -#else -void __init at91_add_device_adc(struct at91_adc_data *data) {} -#endif - -/* -------------------------------------------------------------------- */ -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - if (of_have_populated_dt()) - return 0; - - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9261.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9261.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9261.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * */ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk/at91_pmc.h> - -#include <asm/proc-fns.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/system_misc.h> #include <mach/cpu.h> -#include <mach/at91sam9261.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91SAM9261_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91SAM9261_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91SAM9261_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9261_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9261_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9261_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91SAM9261_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udc_clk = { - .name = "udc_clk", - .pmc_mask = 1 << AT91SAM9261_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91SAM9261_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc2_clk = { - .name = "ssc2_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc0_clk = { - .name = "tc0_clk", - .pmc_mask = 1 << AT91SAM9261_ID_TC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc1_clk = { - .name = "tc1_clk", - .pmc_mask = 1 << AT91SAM9261_ID_TC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc2_clk = { - .name = "tc2_clk", - .pmc_mask = 1 << AT91SAM9261_ID_TC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91SAM9261_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9261_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; - -/* HClocks */ -static struct clk hck0 = { - .name = "hck0", - .pmc_mask = AT91_PMC_HCK0, - .type = CLK_TYPE_SYSTEM, - .id = 0, -}; -static struct clk hck1 = { - .name = "hck1", - .pmc_mask = AT91_PMC_HCK1, - .type = CLK_TYPE_SYSTEM, - .id = 1, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc_clk, - &udc_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ssc2_clk, - &tc0_clk, - &tc1_clk, - &tc2_clk, - &ohci_clk, - &lcdc_clk, - // irq0 .. irq2 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("hclk", "at91sam9261-lcdfb.0", &hck1), - CLKDEV_CON_DEV_ID("hclk", "at91sam9g10-lcdfb.0", &hck1), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), - CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc2_clk), - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioC_clk), - /* more lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), - CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &hck0), - CLKDEV_CON_DEV_ID("hclk", "600000.fb", &hck1), - CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), - CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91sam9261_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); - - clk_register(&hck0); - clk_register(&hck1); -} -#else -#define at91sam9261_register_clocks NULL -#endif -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91sam9261_gpio[] __initdata = { - { - .id = AT91SAM9261_ID_PIOA, - .regbase = AT91SAM9261_BASE_PIOA, - }, { - .id = AT91SAM9261_ID_PIOB, - .regbase = AT91SAM9261_BASE_PIOB, - }, { - .id = AT91SAM9261_ID_PIOC, - .regbase = AT91SAM9261_BASE_PIOC, - } -}; /* -------------------------------------------------------------------- * AT91SAM9261 processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9261_map_io(void) -{ - if (cpu_is_at91sam9g10()) - at91_init_sram(0, AT91SAM9G10_SRAM_BASE, AT91SAM9G10_SRAM_SIZE); - else - at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE); -} - -static void __init at91sam9261_ioremap_registers(void) -{ - at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); - at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); - at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); - at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX); - at91_pm_set_standby(at91sam9_sdram_standby); -} - static void __init at91sam9261_initialize(void) { arm_pm_idle = at91sam9_idle; at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); - - /* Register GPIO subsystem */ - at91_gpio_init(at91sam9261_gpio, 3); -} - -static struct resource rstc_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_RSTC, - .end = AT91SAM9261_BASE_RSTC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9261_BASE_SDRAMC, - .end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device rstc_device = { - .name = "at91-sam9260-reset", - .resource = rstc_resources, - .num_resources = ARRAY_SIZE(rstc_resources), -}; - -static struct resource shdwc_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SHDWC, - .end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device shdwc_device = { - .name = "at91-poweroff", - .resource = shdwc_resources, - .num_resources = ARRAY_SIZE(shdwc_resources), -}; - -static void __init at91sam9261_register_devices(void) -{ - platform_device_register(&rstc_device); - platform_device_register(&shdwc_device); -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 4, /* Serial Synchronous Controller 2 */ - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* LCD Controller */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ -}; - -static void __init at91sam9261_init_time(void) -{ - at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); } AT91_SOC_START(at91sam9261) - .map_io = at91sam9261_map_io, - .default_irq_priority = at91sam9261_default_irq_priority, - .extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) - | (1 << AT91SAM9261_ID_IRQ2), - .ioremap_registers = at91sam9261_ioremap_registers, - .register_clocks = at91sam9261_register_clocks, - .register_devices = at91sam9261_register_devices, .init = at91sam9261_initialize, - .init_time = at91sam9261_init_time, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9261_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9261_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91sam9261_devices.c - * - * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> - * Copyright (C) 2005 David Brownell - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <linux/fb.h> -#include <video/atmel_lcdc.h> - -#include <mach/at91sam9261.h> -#include <mach/at91sam9261_matrix.h> -#include <mach/at91_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "board.h" -#include "generic.h" -#include "gpio.h" - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91SAM9261_UHP_BASE, - .end = AT91SAM9261_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_UHP, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91sam9261_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE) -static struct at91_udc_data udc_data; - -static struct resource udc_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_UDP, - .end = AT91SAM9261_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_UDP, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = udc_resources, - .num_resources = ARRAY_SIZE(udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - - /* Pullup pin is handled internally by USB device peripheral */ - - udc_data = *data; - platform_device_register(&at91sam9261_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc_data; - -static struct resource mmc_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_MCI, - .end = AT91SAM9261_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_MCI, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_mmc_device = { - .name = "atmel_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc_data, - }, - .resource = mmc_resources, - .num_resources = ARRAY_SIZE(mmc_resources), -}; - -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - if (!data) - return; - - if (data->slot[0].bus_width) { - /* input/irq */ - if (gpio_is_valid(data->slot[0].detect_pin)) { - at91_set_gpio_input(data->slot[0].detect_pin, 1); - at91_set_deglitch(data->slot[0].detect_pin, 1); - } - if (gpio_is_valid(data->slot[0].wp_pin)) - at91_set_gpio_input(data->slot[0].wp_pin, 1); - - /* CLK */ - at91_set_B_periph(AT91_PIN_PA2, 0); - - /* CMD */ - at91_set_B_periph(AT91_PIN_PA1, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA0, 1); - if (data->slot[0].bus_width == 4) { - at91_set_B_periph(AT91_PIN_PA4, 1); - at91_set_B_periph(AT91_PIN_PA5, 1); - at91_set_B_periph(AT91_PIN_PA6, 1); - } - - mmc_data = *data; - platform_device_register(&at91sam9261_mmc_device); - } -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device atmel_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ - at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ - - nand_data = *data; - platform_device_register(&atmel_nand_device); -} - -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PA7, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA8, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91sam9261_twi_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PA7, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA7, 1); - - at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA8, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9261_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_TWI, - .end = AT91SAM9261_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_TWI, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_twi_device = { - .id = 0, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* IP version is not the same on 9261 and g10 */ - if (cpu_is_at91sam9g10()) { - at91sam9261_twi_device.name = "i2c-at91sam9g10"; - /* I2C PIO must not be configured as open-drain on this chip */ - } else { - at91sam9261_twi_device.name = "i2c-at91sam9261"; - at91_set_multi_drive(AT91_PIN_PA7, 1); - at91_set_multi_drive(AT91_PIN_PA8, 1); - } - - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */ - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9261_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SPI0, - .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_SPI0, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SPI1, - .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_SPI1, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (!gpio_is_valid(cs_pin)) - continue; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ - at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ - - platform_device_register(&at91sam9261_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ - - platform_device_register(&at91sam9261_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_pdata lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91SAM9261_LCDC_BASE, - .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_LCDC, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -#if defined(CONFIG_FB_INTSRAM) - [2] = { - .start = AT91SAM9261_SRAM_BASE, - .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -#endif -}; - -static struct platform_device at91_lcdc_device = { - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) -{ - if (!data) { - return; - } - - if (cpu_is_at91sam9g10()) - at91_lcdc_device.name = "at91sam9g10-lcdfb"; - else - at91_lcdc_device.name = "at91sam9261-lcdfb"; - -#if defined(CONFIG_FB_ATMEL_STN) - at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ - at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */ - at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ -#else - at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ - at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ - at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ - at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ - at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ - at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ - at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ - at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ - at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ -#endif - - if (ARRAY_SIZE(lcdc_resources) > 2) { - void __iomem *fb; - struct resource *fb_res = &lcdc_resources[2]; - size_t fb_len = resource_size(fb_res); - - fb = ioremap(fb_res->start, fb_len); - if (fb) { - memset(fb, 0, fb_len); - iounmap(fb); - } - } - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_TCB0, - .end = AT91SAM9261_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_TC0, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_TC0, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_TC1, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_TC1, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_TC2, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_TC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_tcb_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb_resources, - .num_resources = ARRAY_SIZE(tcb_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91sam9261_tcb_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91SAM9261_BASE_RTT, - .end = AT91SAM9261_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91sam9261_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, -}; - -#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) -static void __init at91_add_device_rtt_rtc(void) -{ - at91sam9261_rtt_device.name = "rtc-at91sam9"; - /* - * The second resource is needed: - * GPBR will serve as the storage for RTC time offset - */ - at91sam9261_rtt_device.num_resources = 3; - rtt_resources[1].start = AT91SAM9261_BASE_GPBR + - 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; - rtt_resources[1].end = rtt_resources[1].start + 3; - rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; - rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; -} -#else -static void __init at91_add_device_rtt_rtc(void) -{ - /* Only one resource is needed: RTT not used as RTC */ - at91sam9261_rtt_device.num_resources = 1; -} -#endif - -static void __init at91_add_device_rtt(void) -{ - at91_add_device_rtt_rtc(); - platform_device_register(&at91sam9261_rtt_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91SAM9261_BASE_WDT, - .end = AT91SAM9261_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9261_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91sam9261_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SSC0, - .end = AT91SAM9261_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC0, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_ssc0_device = { - .name = "at91rm9200_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB21, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB22, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB23, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB24, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB25, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB26, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SSC1, - .end = AT91SAM9261_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC1, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_ssc1_device = { - .name = "at91rm9200_ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_B_periph(AT91_PIN_PA17, 1); - if (pins & ATMEL_SSC_TK) - at91_set_B_periph(AT91_PIN_PA18, 1); - if (pins & ATMEL_SSC_TD) - at91_set_B_periph(AT91_PIN_PA19, 1); - if (pins & ATMEL_SSC_RD) - at91_set_B_periph(AT91_PIN_PA20, 1); - if (pins & ATMEL_SSC_RK) - at91_set_B_periph(AT91_PIN_PA21, 1); - if (pins & ATMEL_SSC_RF) - at91_set_B_periph(AT91_PIN_PA22, 1); -} - -static u64 ssc2_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc2_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_SSC2, - .end = AT91SAM9261_BASE_SSC2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC2, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_SSC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9261_ssc2_device = { - .name = "at91rm9200_ssc", - .id = 2, - .dev = { - .dma_mask = &ssc2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc2_resources, - .num_resources = ARRAY_SIZE(ssc2_resources), -}; - -static inline void configure_ssc2_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_B_periph(AT91_PIN_PC25, 1); - if (pins & ATMEL_SSC_TK) - at91_set_B_periph(AT91_PIN_PC26, 1); - if (pins & ATMEL_SSC_TD) - at91_set_B_periph(AT91_PIN_PC27, 1); - if (pins & ATMEL_SSC_RD) - at91_set_B_periph(AT91_PIN_PC28, 1); - if (pins & ATMEL_SSC_RK) - at91_set_B_periph(AT91_PIN_PC29, 1); - if (pins & ATMEL_SSC_RF) - at91_set_B_periph(AT91_PIN_PC30, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91SAM9261_ID_SSC0: - pdev = &at91sam9261_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91SAM9261_ID_SSC1: - pdev = &at91sam9261_ssc1_device; - configure_ssc1_pins(pins); - break; - case AT91SAM9261_ID_SSC2: - pdev = &at91sam9261_ssc2_device; - configure_ssc2_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_DBGU, - .end = AT91SAM9261_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9261_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_US0, - .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_US0, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9261_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_US1, - .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_US1, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9261_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91SAM9261_BASE_US2, - .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9261_ID_US2, - .end = NR_IRQS_LEGACY + AT91SAM9261_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9261_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91sam9261_dbgu_device; - configure_dbgu_pins(); - break; - case AT91SAM9261_ID_US0: - pdev = &at91sam9261_uart0_device; - configure_usart0_pins(pins); - break; - case AT91SAM9261_ID_US1: - pdev = &at91sam9261_uart1_device; - configure_usart1_pins(pins); - break; - case AT91SAM9261_ID_US2: - pdev = &at91sam9261_uart2_device; - configure_usart2_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9263.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9263.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9263.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * */ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk/at91_pmc.h> - -#include <asm/proc-fns.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/system_misc.h> -#include <mach/at91sam9263.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91SAM9263_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91SAM9263_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioCDE_clk = { - .name = "pioCDE_clk", - .pmc_mask = 1 << AT91SAM9263_ID_PIOCDE, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9263_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9263_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9263_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91SAM9263_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91SAM9263_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk can_clk = { - .name = "can_clk", - .pmc_mask = 1 << AT91SAM9263_ID_CAN, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91SAM9263_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91SAM9263_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb_clk = { - .name = "tcb_clk", - .pmc_mask = 1 << AT91SAM9263_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91SAM9263_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91SAM9263_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91SAM9263_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twodge_clk = { - .name = "2dge_clk", - .pmc_mask = 1 << AT91SAM9263_ID_2DGE, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udc_clk = { - .name = "udc_clk", - .pmc_mask = 1 << AT91SAM9263_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91SAM9263_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9263_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91SAM9263_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioCDE_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc0_clk, - &mmc1_clk, - &can_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ac97_clk, - &tcb_clk, - &pwm_clk, - &macb_clk, - &twodge_clk, - &udc_clk, - &isi_clk, - &lcdc_clk, - &dma_clk, - &ohci_clk, - // irq0 .. irq1 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID("hclk", "at91sam9263-lcdfb.0", &lcdc_clk), - CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioCDE_clk), - CLKDEV_CON_ID("pioD", &pioCDE_clk), - CLKDEV_CON_ID("pioE", &pioCDE_clk), - /* more usart lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), - /* more tc lookup table for DT entries */ - CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb_clk), - CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff84000.mmc", &mmc1_clk), - CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffb8000.pwm", &pwm_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91sam9263_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} -#else -#define at91sam9263_register_clocks NULL -#endif - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91sam9263_gpio[] __initdata = { - { - .id = AT91SAM9263_ID_PIOA, - .regbase = AT91SAM9263_BASE_PIOA, - }, { - .id = AT91SAM9263_ID_PIOB, - .regbase = AT91SAM9263_BASE_PIOB, - }, { - .id = AT91SAM9263_ID_PIOCDE, - .regbase = AT91SAM9263_BASE_PIOC, - }, { - .id = AT91SAM9263_ID_PIOCDE, - .regbase = AT91SAM9263_BASE_PIOD, - }, { - .id = AT91SAM9263_ID_PIOCDE, - .regbase = AT91SAM9263_BASE_PIOE, - } -}; /* -------------------------------------------------------------------- * AT91SAM9263 processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9263_map_io(void) -{ - at91_init_sram(0, AT91SAM9263_SRAM0_BASE, AT91SAM9263_SRAM0_SIZE); - at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE); -} - -static void __init at91sam9263_ioremap_registers(void) -{ - at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); - at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); - at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); - at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); - at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); - at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX); - at91_pm_set_standby(at91sam9_sdram_standby); -} - static void __init at91sam9263_initialize(void) { arm_pm_idle = at91sam9_idle; at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); - - /* Register GPIO subsystem */ - at91_gpio_init(at91sam9263_gpio, 5); -} - -static struct resource rstc_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_RSTC, - .end = AT91SAM9263_BASE_RSTC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9263_BASE_SDRAMC0, - .end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device rstc_device = { - .name = "at91-sam9260-reset", - .resource = rstc_resources, - .num_resources = ARRAY_SIZE(rstc_resources), -}; - -static struct resource shdwc_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_SHDWC, - .end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device shdwc_device = { - .name = "at91-poweroff", - .resource = shdwc_resources, - .num_resources = ARRAY_SIZE(shdwc_resources), -}; - -static void __init at91sam9263_register_devices(void) -{ - platform_device_register(&rstc_device); - platform_device_register(&shdwc_device); -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C, D and E */ - 0, - 0, - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface 0 */ - 0, /* Multimedia Card Interface 1 */ - 3, /* CAN */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 5, /* AC97 Controller */ - 0, /* Timer Counter 0, 1 and 2 */ - 0, /* Pulse Width Modulation Controller */ - 3, /* Ethernet */ - 0, - 0, /* 2D Graphic Engine */ - 2, /* USB Device Port */ - 0, /* Image Sensor Interface */ - 3, /* LDC Controller */ - 0, /* DMA Controller */ - 0, - 2, /* USB Host port */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ -}; - -static void __init at91sam9263_init_time(void) -{ - at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); } AT91_SOC_START(at91sam9263) - .map_io = at91sam9263_map_io, - .default_irq_priority = at91sam9263_default_irq_priority, - .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1), - .ioremap_registers = at91sam9263_ioremap_registers, - .register_clocks = at91sam9263_register_clocks, - .register_devices = at91sam9263_register_devices, .init = at91sam9263_initialize, - .init_time = at91sam9263_init_time, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9263_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9263_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91sam9263_devices.c - * - * Copyright (C) 2007 Atmel Corporation. - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <linux/fb.h> -#include <video/atmel_lcdc.h> - -#include <mach/at91sam9263.h> -#include <mach/at91sam9263_matrix.h> -#include <mach/at91_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91SAM9263_UHP_BASE, - .end = AT91SAM9263_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_UHP, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable VBus control for UHP ports */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); - } - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE) -static struct at91_udc_data udc_data; - -static struct resource udc_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_UDP, - .end = AT91SAM9263_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_UDP, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = udc_resources, - .num_resources = ARRAY_SIZE(udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - - /* Pullup pin is handled internally by USB device peripheral */ - - udc_data = *data; - platform_device_register(&at91_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_EMAC, - .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_EMAC, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_eth_device = { - .name = "macb", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */ - at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */ - at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ - - if (!data->is_rmii) { - at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ - at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ - } - - eth_data = *data; - platform_device_register(&at91sam9263_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc0_data, mmc1_data; - -static struct resource mmc0_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_MCI0, - .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_MCI0, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_MCI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_mmc0_device = { - .name = "atmel_mci", - .id = 0, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc0_data, - }, - .resource = mmc0_resources, - .num_resources = ARRAY_SIZE(mmc0_resources), -}; - -static struct resource mmc1_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_MCI1, - .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_MCI1, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_MCI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_mmc1_device = { - .name = "atmel_mci", - .id = 1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc1_data, - }, - .resource = mmc1_resources, - .num_resources = ARRAY_SIZE(mmc1_resources), -}; - -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - unsigned int i; - unsigned int slot_count = 0; - - if (!data) - return; - - for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { - - if (!data->slot[i].bus_width) - continue; - - /* input/irq */ - if (gpio_is_valid(data->slot[i].detect_pin)) { - at91_set_gpio_input(data->slot[i].detect_pin, - 1); - at91_set_deglitch(data->slot[i].detect_pin, - 1); - } - if (gpio_is_valid(data->slot[i].wp_pin)) - at91_set_gpio_input(data->slot[i].wp_pin, 1); - - if (mmc_id == 0) { /* MCI0 */ - switch (i) { - case 0: /* slot A */ - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA0, 1); - if (data->slot[i].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); - } - slot_count++; - break; - case 1: /* slot B */ - /* CMD */ - at91_set_A_periph(AT91_PIN_PA16, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA17, 1); - if (data->slot[i].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA18, 1); - at91_set_A_periph(AT91_PIN_PA19, 1); - at91_set_A_periph(AT91_PIN_PA20, 1); - } - slot_count++; - break; - default: - printk(KERN_ERR - "AT91: SD/MMC slot %d not available\n", i); - break; - } - if (slot_count) { - /* CLK */ - at91_set_A_periph(AT91_PIN_PA12, 0); - - mmc0_data = *data; - platform_device_register(&at91sam9263_mmc0_device); - } - } else if (mmc_id == 1) { /* MCI1 */ - switch (i) { - case 0: /* slot A */ - /* CMD */ - at91_set_A_periph(AT91_PIN_PA7, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA8, 1); - if (data->slot[i].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA9, 1); - at91_set_A_periph(AT91_PIN_PA10, 1); - at91_set_A_periph(AT91_PIN_PA11, 1); - } - slot_count++; - break; - case 1: /* slot B */ - /* CMD */ - at91_set_A_periph(AT91_PIN_PA21, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA22, 1); - if (data->slot[i].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA23, 1); - at91_set_A_periph(AT91_PIN_PA24, 1); - at91_set_A_periph(AT91_PIN_PA25, 1); - } - slot_count++; - break; - default: - printk(KERN_ERR - "AT91: SD/MMC slot %d not available\n", i); - break; - } - if (slot_count) { - /* CLK */ - at91_set_A_periph(AT91_PIN_PA6, 0); - - mmc1_data = *data; - platform_device_register(&at91sam9263_mmc1_device); - } - } - } -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * Compact Flash (PCMCIA or IDE) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ - defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) - -static struct at91_cf_data cf0_data; - -static struct resource cf0_resources[] = { - [0] = { - .start = AT91_CHIPSELECT_4, - .end = AT91_CHIPSELECT_4 + SZ_256M - 1, - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - } -}; - -static struct platform_device cf0_device = { - .id = 0, - .dev = { - .platform_data = &cf0_data, - }, - .resource = cf0_resources, - .num_resources = ARRAY_SIZE(cf0_resources), -}; - -static struct at91_cf_data cf1_data; - -static struct resource cf1_resources[] = { - [0] = { - .start = AT91_CHIPSELECT_5, - .end = AT91_CHIPSELECT_5 + SZ_256M - 1, - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - } -}; - -static struct platform_device cf1_device = { - .id = 1, - .dev = { - .platform_data = &cf1_data, - }, - .resource = cf1_resources, - .num_resources = ARRAY_SIZE(cf1_resources), -}; - -void __init at91_add_device_cf(struct at91_cf_data *data) -{ - unsigned long ebi0_csa; - struct platform_device *pdev; - - if (!data) - return; - - /* - * assign CS4 or CS5 to SMC with Compact Flash logic support, - * we assume SMC timings are configured by board code, - * except True IDE where timings are controlled by driver - */ - ebi0_csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); - switch (data->chipselect) { - case 4: - at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ - ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1; - cf0_data = *data; - pdev = &cf0_device; - break; - case 5: - at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */ - ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2; - cf1_data = *data; - pdev = &cf1_device; - break; - default: - printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", - data->chipselect); - return; - } - at91_matrix_write(AT91_MATRIX_EBI0CSA, ebi0_csa); - - if (gpio_is_valid(data->det_pin)) { - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - } - - if (gpio_is_valid(data->irq_pin)) { - at91_set_gpio_input(data->irq_pin, 1); - at91_set_deglitch(data->irq_pin, 1); - } - - if (gpio_is_valid(data->vcc_pin)) - /* initially off */ - at91_set_gpio_output(data->vcc_pin, 0); - - /* enable EBI controlled pins */ - at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */ - at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */ - at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */ - at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */ - - pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "pata_at91" : "at91_cf"; - platform_device_register(pdev); -} -#else -void __init at91_add_device_cf(struct at91_cf_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9263_BASE_ECC0, - .end = AT91SAM9263_BASE_ECC0 + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9263_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); - at91_matrix_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - nand_data = *data; - platform_device_register(&at91sam9263_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PB4, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PB5, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91sam9263_twi_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9263_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_TWI, - .end = AT91SAM9263_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_TWI, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_twi_device = { - .name = "i2c-at91sam9260", - .id = 0, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9263_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_SPI0, - .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_SPI0, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_SPI1, - .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_SPI1, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (!gpio_is_valid(cs_pin)) - continue; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ - at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ - at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ - - platform_device_register(&at91sam9263_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ - - platform_device_register(&at91sam9263_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) -static u64 ac97_dmamask = DMA_BIT_MASK(32); -static struct ac97c_platform_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_AC97C, - .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_AC97C, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_ac97_device = { - .name = "atmel_ac97c", - .id = 0, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct ac97c_platform_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ - - /* reset */ - if (gpio_is_valid(data->reset_pin)) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *data; - platform_device_register(&at91sam9263_ac97_device); -} -#else -void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * CAN Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE) -static struct resource can_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_CAN, - .end = AT91SAM9263_BASE_CAN + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_CAN, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_CAN, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_can_device = { - .name = "at91_can", - .id = -1, - .resource = can_resources, - .num_resources = ARRAY_SIZE(can_resources), -}; - -void __init at91_add_device_can(struct at91_can_data *data) -{ - at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */ - at91sam9263_can_device.dev.platform_data = data; - - platform_device_register(&at91sam9263_can_device); -} -#else -void __init at91_add_device_can(struct at91_can_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_pdata lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91SAM9263_LCDC_BASE, - .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_LCDC, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .name = "at91sam9263-lcdfb", - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ - at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ - at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ - at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ - at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ - at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ - at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ - at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ - at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Image Sensor Interface - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE) - -struct resource isi_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_ISI, - .end = AT91SAM9263_BASE_ISI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_isi_device = { - .name = "at91_isi", - .id = -1, - .resource = isi_resources, - .num_resources = ARRAY_SIZE(isi_resources), -}; - -void __init at91_add_device_isi(struct isi_platform_data *data, - bool use_pck_as_mck) -{ - at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ - at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ - at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */ - at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */ - at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */ - at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */ - at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */ - at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */ - at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ - at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ - at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ - at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ - at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ - at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ - at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ - - if (use_pck_as_mck) { - at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ - - /* TODO: register the PCK for ISI_MCK and set its parent */ - } -} -#else -void __init at91_add_device_isi(struct isi_platform_data *data, - bool use_pck_as_mck) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_TCB0, - .end = AT91SAM9263_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_TCB, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_TCB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_tcb_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb_resources, - .num_resources = ARRAY_SIZE(tcb_resources), -}; - -#if defined(CONFIG_OF) -static struct of_device_id tcb_ids[] = { - { .compatible = "atmel,at91rm9200-tcb" }, - { /*sentinel*/ } -}; -#endif - -static void __init at91_add_device_tc(void) -{ -#if defined(CONFIG_OF) - struct device_node *np; - - np = of_find_matching_node(NULL, tcb_ids); - if (np) { - of_node_put(np); - return; - } -#endif - - platform_device_register(&at91sam9263_tcb_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt0_resources[] = { - { - .start = AT91SAM9263_BASE_RTT0, - .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91sam9263_rtt0_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt0_resources, -}; - -static struct resource rtt1_resources[] = { - { - .start = AT91SAM9263_BASE_RTT1, - .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91sam9263_rtt1_device = { - .name = "at91_rtt", - .id = 1, - .resource = rtt1_resources, -}; - -#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) -static void __init at91_add_device_rtt_rtc(void) -{ - struct platform_device *pdev; - struct resource *r; - - switch (CONFIG_RTC_DRV_AT91SAM9_RTT) { - case 0: - /* - * The second resource is needed only for the chosen RTT: - * GPBR will serve as the storage for RTC time offset - */ - at91sam9263_rtt0_device.num_resources = 3; - at91sam9263_rtt1_device.num_resources = 1; - pdev = &at91sam9263_rtt0_device; - r = rtt0_resources; - break; - case 1: - at91sam9263_rtt0_device.num_resources = 1; - at91sam9263_rtt1_device.num_resources = 3; - pdev = &at91sam9263_rtt1_device; - r = rtt1_resources; - break; - default: - pr_err("at91sam9263: only supports 2 RTT (%d)\n", - CONFIG_RTC_DRV_AT91SAM9_RTT); - return; - } - - pdev->name = "rtc-at91sam9"; - r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; - r[1].end = r[1].start + 3; - r[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; - r[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; -} -#else -static void __init at91_add_device_rtt_rtc(void) -{ - /* Only one resource is needed: RTT not used as RTC */ - at91sam9263_rtt0_device.num_resources = 1; - at91sam9263_rtt1_device.num_resources = 1; -} -#endif - -static void __init at91_add_device_rtt(void) -{ - at91_add_device_rtt_rtc(); - platform_device_register(&at91sam9263_rtt0_device); - platform_device_register(&at91sam9263_rtt1_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91SAM9263_BASE_WDT, - .end = AT91SAM9263_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9263_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91sam9263_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * PWM - * --------------------------------------------------------------------*/ - -#if IS_ENABLED(CONFIG_PWM_ATMEL) -static struct resource pwm_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_PWMC, - .end = AT91SAM9263_BASE_PWMC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_PWMC, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_PWMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_pwm0_device = { - .name = "at91sam9rl-pwm", - .id = -1, - .resource = pwm_resources, - .num_resources = ARRAY_SIZE(pwm_resources), -}; - -void __init at91_add_device_pwm(u32 mask) -{ - if (mask & (1 << AT91_PWM0)) - at91_set_B_periph(AT91_PIN_PB7, 1); /* enable PWM0 */ - - if (mask & (1 << AT91_PWM1)) - at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ - - if (mask & (1 << AT91_PWM2)) - at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ - - if (mask & (1 << AT91_PWM3)) - at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */ - - platform_device_register(&at91sam9263_pwm0_device); -} -#else -void __init at91_add_device_pwm(u32 mask) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_SSC0, - .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_SSC0, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_ssc0_device = { - .name = "at91rm9200_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_B_periph(AT91_PIN_PB0, 1); - if (pins & ATMEL_SSC_TK) - at91_set_B_periph(AT91_PIN_PB1, 1); - if (pins & ATMEL_SSC_TD) - at91_set_B_periph(AT91_PIN_PB2, 1); - if (pins & ATMEL_SSC_RD) - at91_set_B_periph(AT91_PIN_PB3, 1); - if (pins & ATMEL_SSC_RK) - at91_set_B_periph(AT91_PIN_PB4, 1); - if (pins & ATMEL_SSC_RF) - at91_set_B_periph(AT91_PIN_PB5, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_SSC1, - .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_SSC1, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_ssc1_device = { - .name = "at91rm9200_ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB6, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB7, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB8, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB9, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB10, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB11, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91SAM9263_ID_SSC0: - pdev = &at91sam9263_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91SAM9263_ID_SSC1: - pdev = &at91sam9263_ssc1_device; - configure_ssc1_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) - -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_DBGU, - .end = AT91SAM9263_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9263_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_US0, - .end = AT91SAM9263_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_US0, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9263_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_US1, - .end = AT91SAM9263_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_US1, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9263_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_US2, - .end = AT91SAM9263_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_US2, - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9263_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91sam9263_dbgu_device; - configure_dbgu_pins(); - break; - case AT91SAM9263_ID_US0: - pdev = &at91sam9263_uart0_device; - configure_usart0_pins(pins); - break; - case AT91SAM9263_ID_US1: - pdev = &at91sam9263_uart1_device; - configure_usart1_pins(pins); - break; - case AT91SAM9263_ID_US2: - pdev = &at91sam9263_uart2_device; - configure_usart2_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - if (of_have_populated_dt()) - return 0; - - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9g45.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9g45.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9g45.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * */ -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/clk/at91_pmc.h> -#include <linux/platform_device.h> - -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/system_misc.h> -#include <mach/at91sam9g45.h> -#include <mach/cpu.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioDE_clk = { - .name = "pioDE_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_PIODE, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk trng_clk = { - .name = "trng_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_TRNG, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_US3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi0_clk = { - .name = "twi0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_TWI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi1_clk = { - .name = "twi1_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_TWI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb0_clk = { - .name = "tcb0_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tsc_clk = { - .name = "tsc_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_TSC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uhphs_clk = { - .name = "uhphs_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; - -/* Video decoder clock - Only for sam9m10/sam9m11 */ -static struct clk vdec_clk = { - .name = "vdec_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_VDEC, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk adc_op_clk = { - .name = "adc_op_clk", - .type = CLK_TYPE_PERIPHERAL, - .rate_hz = 300000, -}; - -/* AES/TDES/SHA clock - Only for sam9m11/sam9g56 */ -static struct clk aestdessha_clk = { - .name = "aestdessha_clk", - .pmc_mask = 1 << AT91SAM9G45_ID_AESTDESSHA, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioDE_clk, - &trng_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc0_clk, - &twi0_clk, - &twi1_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &tcb0_clk, - &pwm_clk, - &tsc_clk, - &dma_clk, - &uhphs_clk, - &lcdc_clk, - &ac97_clk, - &macb_clk, - &isi_clk, - &udphs_clk, - &mmc1_clk, - &adc_op_clk, - &aestdessha_clk, - // irq0 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - /* One additional fake clock for ohci */ - CLKDEV_CON_ID("ohci_clk", &uhphs_clk), - CLKDEV_CON_DEV_ID("hclk", "at91sam9g45-lcdfb.0", &lcdc_clk), - CLKDEV_CON_DEV_ID("hclk", "at91sam9g45es-lcdfb.0", &lcdc_clk), - CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), - CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "fffa0000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), - CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), - CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk), - CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk), - CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk), - /* more usart lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), - /* more tc lookup table for DT entries */ - CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk), - CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID("hclk", "600000.gadget", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "600000.gadget", &udphs_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk), - - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioC_clk), - CLKDEV_CON_ID("pioD", &pioDE_clk), - CLKDEV_CON_ID("pioE", &pioDE_clk), - /* Fake adc clock */ - CLKDEV_CON_ID("adc_clk", &tsc_clk), - CLKDEV_CON_DEV_ID(NULL, "fffb8000.pwm", &pwm_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), -}; - -/* - * The two programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static void __init at91sam9g45_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) - clk_register(&vdec_clk); - - clk_register(&pck0); - clk_register(&pck1); -} -#else -#define at91sam9g45_register_clocks NULL -#endif - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = { - { - .id = AT91SAM9G45_ID_PIOA, - .regbase = AT91SAM9G45_BASE_PIOA, - }, { - .id = AT91SAM9G45_ID_PIOB, - .regbase = AT91SAM9G45_BASE_PIOB, - }, { - .id = AT91SAM9G45_ID_PIOC, - .regbase = AT91SAM9G45_BASE_PIOC, - }, { - .id = AT91SAM9G45_ID_PIODE, - .regbase = AT91SAM9G45_BASE_PIOD, - }, { - .id = AT91SAM9G45_ID_PIODE, - .regbase = AT91SAM9G45_BASE_PIOE, - } -}; /* -------------------------------------------------------------------- * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9g45_map_io(void) -{ - at91_init_sram(0, AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE); -} - -static void __init at91sam9g45_ioremap_registers(void) -{ - at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); - at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); - at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); - at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); - at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX); - at91_pm_set_standby(at91_ddr_standby); -} - static void __init at91sam9g45_initialize(void) { arm_pm_idle = at91sam9_idle; at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); - - /* Register GPIO subsystem */ - at91_gpio_init(at91sam9g45_gpio, 5); -} - -static struct resource rstc_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_RSTC, - .end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9G45_BASE_DDRSDRC1, - .end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = AT91SAM9G45_BASE_DDRSDRC0, - .end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device rstc_device = { - .name = "at91-sam9g45-reset", - .resource = rstc_resources, - .num_resources = ARRAY_SIZE(rstc_resources), -}; - -static struct resource shdwc_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_SHDWC, - .end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device shdwc_device = { - .name = "at91-poweroff", - .resource = shdwc_resources, - .num_resources = ARRAY_SIZE(shdwc_resources), -}; - -static void __init at91sam9g45_register_devices(void) -{ - platform_device_register(&rstc_device); - platform_device_register(&shdwc_device); -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 1, /* Parallel IO Controller D and E */ - 0, - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 0, /* Multimedia Card Interface 0 */ - 6, /* Two-Wire Interface 0 */ - 6, /* Two-Wire Interface 1 */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ - 0, /* Pulse Width Modulation Controller */ - 0, /* Touch Screen Controller */ - 0, /* DMA Controller */ - 2, /* USB Host High Speed port */ - 3, /* LDC Controller */ - 5, /* AC97 Controller */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 2, /* USB Device High speed port */ - 0, /* AESTDESSHA Crypto HW Accelerators */ - 0, /* Multimedia Card Interface 1 */ - 0, - 0, /* Advanced Interrupt Controller (IRQ0) */ -}; - -static void __init at91sam9g45_init_time(void) -{ - at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); } AT91_SOC_START(at91sam9g45) - .map_io = at91sam9g45_map_io, - .default_irq_priority = at91sam9g45_default_irq_priority, - .extern_irq = (1 << AT91SAM9G45_ID_IRQ0), - .ioremap_registers = at91sam9g45_ioremap_registers, - .register_clocks = at91sam9g45_register_clocks, - .register_devices = at91sam9g45_register_devices, .init = at91sam9g45_initialize, - .init_time = at91sam9g45_init_time, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9g45_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9g45_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * On-Chip devices setup code for the AT91SAM9G45 family - * - * Copyright (C) 2009 Atmel Corporation. - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/clk.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> -#include <linux/atmel-mci.h> -#include <linux/platform_data/crypto-atmel.h> - -#include <linux/platform_data/at91_adc.h> - -#include <linux/fb.h> -#include <video/atmel_lcdc.h> - -#include <mach/at91sam9g45.h> -#include <mach/at91sam9g45_matrix.h> -#include <mach/at91_matrix.h> -#include <mach/at91sam9_smc.h> -#include <linux/platform_data/dma-atmel.h> -#include <mach/atmel-mci.h> -#include <mach/hardware.h> - -#include <media/atmel-isi.h> - -#include "board.h" -#include "generic.h" -#include "clock.h" -#include "gpio.h" - - -/* -------------------------------------------------------------------- - * HDMAC - AHB DMA Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) -static u64 hdmac_dmamask = DMA_BIT_MASK(32); - -static struct resource hdmac_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_DMA, - .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_DMA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_DMA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at_hdmac_device = { - .name = "at91sam9g45_dma", - .id = -1, - .dev = { - .dma_mask = &hdmac_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = hdmac_resources, - .num_resources = ARRAY_SIZE(hdmac_resources), -}; - -void __init at91_add_device_hdmac(void) -{ - platform_device_register(&at_hdmac_device); -} -#else -void __init at91_add_device_hdmac(void) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Host (OHCI) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_ohci_data; - -static struct resource usbh_ohci_resources[] = { - [0] = { - .start = AT91SAM9G45_OHCI_BASE, - .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_UHPHS, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_UHPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_ohci_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_ohci_data, - }, - .resource = usbh_ohci_resources, - .num_resources = ARRAY_SIZE(usbh_ohci_resources), -}; - -void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable VBus control for UHP ports */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); - } - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_ohci_data = *data; - platform_device_register(&at91_usbh_ohci_device); -} -#else -void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Host HS (EHCI) - * Needs an OHCI host for low and full speed management - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE) -static u64 ehci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_ehci_data; - -static struct resource usbh_ehci_resources[] = { - [0] = { - .start = AT91SAM9G45_EHCI_BASE, - .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_UHPHS, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_UHPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_ehci_device = { - .name = "atmel-ehci", - .id = -1, - .dev = { - .dma_mask = &ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_ehci_data, - }, - .resource = usbh_ehci_resources, - .num_resources = ARRAY_SIZE(usbh_ehci_resources), -}; - -void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - /* Enable VBus control for UHP ports */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); - } - - usbh_ehci_data = *data; - platform_device_register(&at91_usbh_ehci_device); -} -#else -void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB HS Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE) -static struct resource usba_udc_resources[] = { - [0] = { - .start = AT91SAM9G45_UDPHS_FIFO, - .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9G45_BASE_UDPHS, - .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_UDPHS, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_UDPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -static struct usba_ep_data usba_udc_ep[] __initdata = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 2, 1, 1), - EP("ep2", 2, 1024, 2, 1, 1), - EP("ep3", 3, 1024, 3, 1, 0), - EP("ep4", 4, 1024, 3, 1, 0), - EP("ep5", 5, 1024, 3, 1, 1), - EP("ep6", 6, 1024, 3, 1, 1), -}; - -#undef EP - -/* - * pdata doesn't have room for any endpoints, so we need to - * append room for the ones we need right after it. - */ -static struct { - struct usba_platform_data pdata; - struct usba_ep_data ep[7]; -} usba_udc_data; - -static struct platform_device at91_usba_udc_device = { - .name = "atmel_usba_udc", - .id = -1, - .dev = { - .platform_data = &usba_udc_data.pdata, - }, - .resource = usba_udc_resources, - .num_resources = ARRAY_SIZE(usba_udc_resources), -}; - -void __init at91_add_device_usba(struct usba_platform_data *data) -{ - usba_udc_data.pdata.vbus_pin = -EINVAL; - usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - - if (data && gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - usba_udc_data.pdata.vbus_pin = data->vbus_pin; - } - - /* Pullup pin is handled internally by USB device peripheral */ - - platform_device_register(&at91_usba_udc_device); -} -#else -void __init at91_add_device_usba(struct usba_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_EMAC, - .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_EMAC, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_eth_device = { - .name = "macb", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */ - at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */ - at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */ - } - - eth_data = *data; - platform_device_register(&at91sam9g45_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc0_data, mmc1_data; - -static struct resource mmc0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_MCI0, - .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_MCI0, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_MCI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_mmc0_device = { - .name = "atmel_mci", - .id = 0, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc0_data, - }, - .resource = mmc0_resources, - .num_resources = ARRAY_SIZE(mmc0_resources), -}; - -static struct resource mmc1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_MCI1, - .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_MCI1, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_MCI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_mmc1_device = { - .name = "atmel_mci", - .id = 1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc1_data, - }, - .resource = mmc1_resources, - .num_resources = ARRAY_SIZE(mmc1_resources), -}; - -/* Consider only one slot : slot 0 */ -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - - if (!data) - return; - - /* Must have at least one usable slot */ - if (!data->slot[0].bus_width) - return; - -#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) - { - struct at_dma_slave *atslave; - struct mci_dma_data *alt_atslave; - - alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL); - atslave = &alt_atslave->sdata; - - /* DMA slave channel configuration */ - atslave->dma_dev = &at_hdmac_device.dev; - atslave->cfg = ATC_FIFOCFG_HALFFIFO - | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; - if (mmc_id == 0) /* MCI0 */ - atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0) - | ATC_DST_PER(AT_DMA_ID_MCI0); - - else /* MCI1 */ - atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1) - | ATC_DST_PER(AT_DMA_ID_MCI1); - - data->dma_slave = alt_atslave; - } -#endif - - - /* input/irq */ - if (gpio_is_valid(data->slot[0].detect_pin)) { - at91_set_gpio_input(data->slot[0].detect_pin, 1); - at91_set_deglitch(data->slot[0].detect_pin, 1); - } - if (gpio_is_valid(data->slot[0].wp_pin)) - at91_set_gpio_input(data->slot[0].wp_pin, 1); - - if (mmc_id == 0) { /* MCI0 */ - - /* CLK */ - at91_set_A_periph(AT91_PIN_PA0, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); - - /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ - at91_set_A_periph(AT91_PIN_PA2, 1); - if (data->slot[0].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); - if (data->slot[0].bus_width == 8) { - at91_set_A_periph(AT91_PIN_PA6, 1); - at91_set_A_periph(AT91_PIN_PA7, 1); - at91_set_A_periph(AT91_PIN_PA8, 1); - at91_set_A_periph(AT91_PIN_PA9, 1); - } - } - - mmc0_data = *data; - platform_device_register(&at91sam9g45_mmc0_device); - - } else { /* MCI1 */ - - /* CLK */ - at91_set_A_periph(AT91_PIN_PA31, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA22, 1); - - /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ - at91_set_A_periph(AT91_PIN_PA23, 1); - if (data->slot[0].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA24, 1); - at91_set_A_periph(AT91_PIN_PA25, 1); - at91_set_A_periph(AT91_PIN_PA26, 1); - if (data->slot[0].bus_width == 8) { - at91_set_A_periph(AT91_PIN_PA27, 1); - at91_set_A_periph(AT91_PIN_PA28, 1); - at91_set_A_periph(AT91_PIN_PA29, 1); - at91_set_A_periph(AT91_PIN_PA30, 1); - } - } - - mmc1_data = *data; - platform_device_register(&at91sam9g45_mmc1_device); - - } -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9G45_BASE_ECC, - .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9g45_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - nand_data = *data; - platform_device_register(&at91sam9g45_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) -static struct i2c_gpio_platform_data pdata_i2c0 = { - .sda_pin = AT91_PIN_PA20, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA21, - .scl_is_open_drain = 1, - .udelay = 5, /* ~100 kHz */ -}; - -static struct platform_device at91sam9g45_twi0_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata_i2c0, -}; - -static struct i2c_gpio_platform_data pdata_i2c1 = { - .sda_pin = AT91_PIN_PB10, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PB11, - .scl_is_open_drain = 1, - .udelay = 5, /* ~100 kHz */ -}; - -static struct platform_device at91sam9g45_twi1_device = { - .name = "i2c-gpio", - .id = 1, - .dev.platform_data = &pdata_i2c1, -}; - -void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) -{ - i2c_register_board_info(i2c_id, devices, nr_devices); - - if (i2c_id == 0) { - at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA20, 1); - - at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA21, 1); - - platform_device_register(&at91sam9g45_twi0_device); - } else { - at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PB10, 1); - - at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PB11, 1); - - platform_device_register(&at91sam9g45_twi1_device); - } -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) -static struct resource twi0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TWI0, - .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_TWI0, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_TWI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_twi0_device = { - .name = "i2c-at91sam9g10", - .id = 0, - .resource = twi0_resources, - .num_resources = ARRAY_SIZE(twi0_resources), -}; - -static struct resource twi1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TWI1, - .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_TWI1, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_TWI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_twi1_device = { - .name = "i2c-at91sam9g10", - .id = 1, - .resource = twi1_resources, - .num_resources = ARRAY_SIZE(twi1_resources), -}; - -void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) -{ - i2c_register_board_info(i2c_id, devices, nr_devices); - - /* pins used for TWI interface */ - if (i2c_id == 0) { - at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */ - at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */ - - platform_device_register(&at91sam9g45_twi0_device); - } else { - at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */ - at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */ - - platform_device_register(&at91sam9g45_twi1_device); - } -} -#else -void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_SPI0, - .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_SPI0, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_SPI1, - .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_SPI1, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (!gpio_is_valid(cs_pin)) - continue; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */ - - platform_device_register(&at91sam9g45_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */ - - platform_device_register(&at91sam9g45_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) -static u64 ac97_dmamask = DMA_BIT_MASK(32); -static struct ac97c_platform_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_AC97C, - .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AC97C, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_ac97_device = { - .name = "atmel_ac97c", - .id = 0, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct ac97c_platform_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */ - - /* reset */ - if (gpio_is_valid(data->reset_pin)) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *data; - platform_device_register(&at91sam9g45_ac97_device); -} -#else -void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * Image Sensor Interface - * -------------------------------------------------------------------- */ -#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE) -static u64 isi_dmamask = DMA_BIT_MASK(32); -static struct isi_platform_data isi_data; - -struct resource isi_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_ISI, - .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_ISI, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_ISI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_isi_device = { - .name = "atmel_isi", - .id = 0, - .dev = { - .dma_mask = &isi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &isi_data, - }, - .resource = isi_resources, - .num_resources = ARRAY_SIZE(isi_resources), -}; - -static struct clk_lookup isi_mck_lookups[] = { - CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL), -}; - -void __init at91_add_device_isi(struct isi_platform_data *data, - bool use_pck_as_mck) -{ - struct clk *pck; - struct clk *parent; - - if (!data) - return; - isi_data = *data; - - at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */ - at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */ - at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */ - at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */ - at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */ - at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */ - at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */ - at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */ - at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */ - at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */ - at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */ - at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */ - at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */ - - platform_device_register(&at91sam9g45_isi_device); - - if (use_pck_as_mck) { - at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */ - - pck = clk_get(NULL, "pck1"); - parent = clk_get(NULL, "plla"); - - BUG_ON(IS_ERR(pck) || IS_ERR(parent)); - - if (clk_set_parent(pck, parent)) { - pr_err("Failed to set PCK's parent\n"); - } else { - /* Register PCK as ISI_MCK */ - isi_mck_lookups[0].clk = pck; - clkdev_add_table(isi_mck_lookups, - ARRAY_SIZE(isi_mck_lookups)); - } - - clk_put(pck); - clk_put(parent); - } -} -#else -void __init at91_add_device_isi(struct isi_platform_data *data, - bool use_pck_as_mck) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_pdata lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91SAM9G45_LCDC_BASE, - .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_LCDC, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) -{ - if (!data) - return; - - if (cpu_is_at91sam9g45es()) - at91_lcdc_device.name = "at91sam9g45es-lcdfb"; - else - at91_lcdc_device.name = "at91sam9g45-lcdfb"; - - at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ - - at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */ - at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */ - at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */ - at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */ - at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */ - at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */ - at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */ - at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */ - at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */ - at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */ - at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */ - at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */ - at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */ - at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */ - at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */ - at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB -static struct resource tcb0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TCB0, - .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_TCB, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_TCB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_tcb0_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb0_resources, - .num_resources = ARRAY_SIZE(tcb0_resources), -}; - -/* TCB1 begins with TC3 */ -static struct resource tcb1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TCB1, - .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_TCB, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_TCB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_tcb1_device = { - .name = "atmel_tcb", - .id = 1, - .resource = tcb1_resources, - .num_resources = ARRAY_SIZE(tcb1_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91sam9g45_tcb0_device); - platform_device_register(&at91sam9g45_tcb1_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) -static struct resource rtc_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_RTC, - .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_rtc_device = { - .name = "at91_rtc", - .id = -1, - .resource = rtc_resources, - .num_resources = ARRAY_SIZE(rtc_resources), -}; - -static void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91sam9g45_rtc_device); -} -#else -static void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * ADC and touchscreen - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_AT91_ADC) -static struct at91_adc_data adc_data; - -static struct resource adc_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TSC, - .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_TSC, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_TSC, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91_adc_device = { - .name = "at91sam9g45-adc", - .id = -1, - .dev = { - .platform_data = &adc_data, - }, - .resource = adc_resources, - .num_resources = ARRAY_SIZE(adc_resources), -}; - -static struct at91_adc_trigger at91_adc_triggers[] = { - [0] = { - .name = "external-rising", - .value = 1, - .is_external = true, - }, - [1] = { - .name = "external-falling", - .value = 2, - .is_external = true, - }, - [2] = { - .name = "external-any", - .value = 3, - .is_external = true, - }, - [3] = { - .name = "continuous", - .value = 6, - .is_external = false, - }, -}; - -void __init at91_add_device_adc(struct at91_adc_data *data) -{ - if (!data) - return; - - if (test_bit(0, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD20, 0); - if (test_bit(1, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD21, 0); - if (test_bit(2, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD22, 0); - if (test_bit(3, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD23, 0); - if (test_bit(4, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD24, 0); - if (test_bit(5, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD25, 0); - if (test_bit(6, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD26, 0); - if (test_bit(7, &data->channels_used)) - at91_set_gpio_input(AT91_PIN_PD27, 0); - - if (data->use_external_triggers) - at91_set_A_periph(AT91_PIN_PD28, 0); - - data->startup_time = 40; - data->trigger_number = 4; - data->trigger_list = at91_adc_triggers; - - adc_data = *data; - platform_device_register(&at91_adc_device); -} -#else -void __init at91_add_device_adc(struct at91_adc_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91SAM9G45_BASE_RTT, - .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91sam9g45_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, -}; - -#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) -static void __init at91_add_device_rtt_rtc(void) -{ - at91sam9g45_rtt_device.name = "rtc-at91sam9"; - /* - * The second resource is needed: - * GPBR will serve as the storage for RTC time offset - */ - at91sam9g45_rtt_device.num_resources = 3; - rtt_resources[1].start = AT91SAM9G45_BASE_GPBR + - 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; - rtt_resources[1].end = rtt_resources[1].start + 3; - rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; - rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; -} -#else -static void __init at91_add_device_rtt_rtc(void) -{ - /* Only one resource is needed: RTT not used as RTC */ - at91sam9g45_rtt_device.num_resources = 1; -} -#endif - -static void __init at91_add_device_rtt(void) -{ - at91_add_device_rtt_rtc(); - platform_device_register(&at91sam9g45_rtt_device); -} - - -/* -------------------------------------------------------------------- - * TRNG - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_HW_RANDOM_ATMEL) || defined(CONFIG_HW_RANDOM_ATMEL_MODULE) -static struct resource trng_resources[] = { - { - .start = AT91SAM9G45_BASE_TRNG, - .end = AT91SAM9G45_BASE_TRNG + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device at91sam9g45_trng_device = { - .name = "atmel-trng", - .id = -1, - .resource = trng_resources, - .num_resources = ARRAY_SIZE(trng_resources), -}; - -static void __init at91_add_device_trng(void) -{ - platform_device_register(&at91sam9g45_trng_device); -} -#else -static void __init at91_add_device_trng(void) {} -#endif - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91SAM9G45_BASE_WDT, - .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9g45_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91sam9g45_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * PWM - * --------------------------------------------------------------------*/ - -#if IS_ENABLED(CONFIG_PWM_ATMEL) -static struct resource pwm_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_PWMC, - .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_PWMC, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_PWMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_pwm0_device = { - .name = "at91sam9rl-pwm", - .id = -1, - .resource = pwm_resources, - .num_resources = ARRAY_SIZE(pwm_resources), -}; - -void __init at91_add_device_pwm(u32 mask) -{ - if (mask & (1 << AT91_PWM0)) - at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */ - - if (mask & (1 << AT91_PWM1)) - at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */ - - if (mask & (1 << AT91_PWM2)) - at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */ - - if (mask & (1 << AT91_PWM3)) - at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */ - - platform_device_register(&at91sam9g45_pwm0_device); -} -#else -void __init at91_add_device_pwm(u32 mask) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_SSC0, - .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_SSC0, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_ssc0_device = { - .name = "at91sam9g45_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PD1, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PD0, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PD2, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PD3, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PD4, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PD5, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_SSC1, - .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_SSC1, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_ssc1_device = { - .name = "at91sam9g45_ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PD14, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PD12, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PD10, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PD11, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PD13, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PD15, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91SAM9G45_ID_SSC0: - pdev = &at91sam9g45_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91SAM9G45_ID_SSC1: - pdev = &at91sam9g45_ssc1_device; - configure_ssc1_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_DBGU, - .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9g45_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_US0, - .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_US0, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9g45_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_US1, - .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_US1, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9g45_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_US2, - .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_US2, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9g45_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_US3, - .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_US3, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart3_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9g45_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .dma_mask = &uart3_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart3_data, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */ - at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91sam9g45_dbgu_device; - configure_dbgu_pins(); - break; - case AT91SAM9G45_ID_US0: - pdev = &at91sam9g45_uart0_device; - configure_usart0_pins(pins); - break; - case AT91SAM9G45_ID_US1: - pdev = &at91sam9g45_uart1_device; - configure_usart1_pins(pins); - break; - case AT91SAM9G45_ID_US2: - pdev = &at91sam9g45_uart2_device; - configure_usart2_pins(pins); - break; - case AT91SAM9G45_ID_US3: - pdev = &at91sam9g45_uart3_device; - configure_usart3_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - -/* -------------------------------------------------------------------- - * SHA1/SHA256 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_CRYPTO_DEV_ATMEL_SHA) || defined(CONFIG_CRYPTO_DEV_ATMEL_SHA_MODULE) -static struct resource sha_resources[] = { - { - .start = AT91SAM9G45_BASE_SHA, - .end = AT91SAM9G45_BASE_SHA + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_sha_device = { - .name = "atmel_sha", - .id = -1, - .resource = sha_resources, - .num_resources = ARRAY_SIZE(sha_resources), -}; - -static void __init at91_add_device_sha(void) -{ - platform_device_register(&at91sam9g45_sha_device); -} -#else -static void __init at91_add_device_sha(void) {} -#endif - -/* -------------------------------------------------------------------- - * DES/TDES - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_CRYPTO_DEV_ATMEL_TDES) || defined(CONFIG_CRYPTO_DEV_ATMEL_TDES_MODULE) -static struct resource tdes_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_TDES, - .end = AT91SAM9G45_BASE_TDES + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_tdes_device = { - .name = "atmel_tdes", - .id = -1, - .resource = tdes_resources, - .num_resources = ARRAY_SIZE(tdes_resources), -}; - -static void __init at91_add_device_tdes(void) -{ - platform_device_register(&at91sam9g45_tdes_device); -} -#else -static void __init at91_add_device_tdes(void) {} -#endif - -/* -------------------------------------------------------------------- - * AES - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_CRYPTO_DEV_ATMEL_AES) || defined(CONFIG_CRYPTO_DEV_ATMEL_AES_MODULE) -static struct crypto_platform_data aes_data; -static struct crypto_dma_data alt_atslave; -static u64 aes_dmamask = DMA_BIT_MASK(32); - -static struct resource aes_resources[] = { - [0] = { - .start = AT91SAM9G45_BASE_AES, - .end = AT91SAM9G45_BASE_AES + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9g45_aes_device = { - .name = "atmel_aes", - .id = -1, - .dev = { - .dma_mask = &aes_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &aes_data, - }, - .resource = aes_resources, - .num_resources = ARRAY_SIZE(aes_resources), -}; - -static void __init at91_add_device_aes(void) -{ - struct at_dma_slave *atslave; - - /* DMA TX slave channel configuration */ - atslave = &alt_atslave.txdata; - atslave->dma_dev = &at_hdmac_device.dev; - atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_SRC_H2SEL_HW | - ATC_SRC_PER(AT_DMA_ID_AES_RX); - - /* DMA RX slave channel configuration */ - atslave = &alt_atslave.rxdata; - atslave->dma_dev = &at_hdmac_device.dev; - atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_DST_H2SEL_HW | - ATC_DST_PER(AT_DMA_ID_AES_TX); - - aes_data.dma_slave = &alt_atslave; - platform_device_register(&at91sam9g45_aes_device); -} -#else -static void __init at91_add_device_aes(void) {} -#endif - -/* -------------------------------------------------------------------- */ -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - if (of_have_populated_dt()) - return 0; - - at91_add_device_hdmac(); - at91_add_device_rtc(); - at91_add_device_rtt(); - at91_add_device_trng(); - at91_add_device_watchdog(); - at91_add_device_tc(); - at91_add_device_sha(); - at91_add_device_tdes(); - at91_add_device_aes(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9n12.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9n12.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9n12.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:9 @ * Licensed under GPLv2 or later. */ -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/clk/at91_pmc.h> +#include <asm/system_misc.h> +#include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <mach/at91sam9n12.h> -#include <mach/cpu.h> - -#include "board.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioAB_clk = { - .name = "pioAB_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_PIOAB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioCD_clk = { - .name = "pioCD_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_PIOCD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_USART0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_USART1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_USART2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_USART3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi0_clk = { - .name = "twi0_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_TWI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi1_clk = { - .name = "twi1_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_TWI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uart0_clk = { - .name = "uart0_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_UART0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uart1_clk = { - .name = "uart1_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_UART1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb_clk = { - .name = "tcb_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_PWM, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uhp_clk = { - .name = "uhp", - .pmc_mask = 1 << AT91SAM9N12_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udp_clk = { - .name = "udp_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc_clk = { - .name = "ssc_clk", - .pmc_mask = 1 << AT91SAM9N12_ID_SSC, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioAB_clk, - &pioCD_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &twi0_clk, - &twi1_clk, - &mmc_clk, - &spi0_clk, - &spi1_clk, - &lcdc_clk, - &uart0_clk, - &uart1_clk, - &tcb_clk, - &pwm_clk, - &adc_clk, - &dma_clk, - &uhp_clk, - &udp_clk, - &ssc_clk, -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc_clk), - CLKDEV_CON_DEV_ID(NULL, "f0010000.ssc", &ssc_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), - CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f0000000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), - /* additional fake clock for macb_hclk */ - CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk), - CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk), - CLKDEV_CON_DEV_ID(NULL, "f8034000.pwm", &pwm_clk), -}; - -/* - * The two programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static void __init at91sam9n12_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - clk_register(&pck0); - clk_register(&pck1); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - -} -#else -#define at91sam9n12_register_clocks NULL -#endif /* -------------------------------------------------------------------- * AT91SAM9N12 processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9n12_map_io(void) -{ - at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE); -} - static void __init at91sam9n12_initialize(void) { at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC); } AT91_SOC_START(at91sam9n12) - .map_io = at91sam9n12_map_io, - .register_clocks = at91sam9n12_register_clocks, .init = at91sam9n12_initialize, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9rl.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9rl.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9rl.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:12 @ * more details. */ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk/at91_pmc.h> - -#include <asm/proc-fns.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/system_misc.h> #include <mach/cpu.h> #include <mach/at91_dbgu.h> -#include <mach/at91sam9rl.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" -#include "pm.h" - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" - -/* - * The peripheral clocks. - */ -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioD_clk = { - .name = "pioD_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_PIOD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_US3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi0_clk = { - .name = "twi0_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TWI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi1_clk = { - .name = "twi1_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TWI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi_clk = { - .name = "spi_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_SPI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc0_clk = { - .name = "tc0_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc1_clk = { - .name = "tc1_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tc2_clk = { - .name = "tc2_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TC2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tsc_clk = { - .name = "tsc_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_TSC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91SAM9RL_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_op_clk = { - .name = "adc_op_clk", - .type = CLK_TYPE_PERIPHERAL, - .rate_hz = 1000000, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioD_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc_clk, - &twi0_clk, - &twi1_clk, - &spi_clk, - &ssc0_clk, - &ssc1_clk, - &tc0_clk, - &tc1_clk, - &tc2_clk, - &pwm_clk, - &tsc_clk, - &dma_clk, - &udphs_clk, - &lcdc_clk, - &ac97_clk, - &adc_op_clk, - // irq0 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("hclk", "at91sam9rl-lcdfb.0", &lcdc_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), - CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), - CLKDEV_CON_ID("pioB", &pioB_clk), - CLKDEV_CON_ID("pioC", &pioC_clk), - CLKDEV_CON_ID("pioD", &pioD_clk), - /* more lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "ffffb800.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "ffffbc00.serial", &usart3_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffa4000.mmc", &mmc_clk), - CLKDEV_CON_DEV_ID(NULL, "fffa8000.i2c", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID(NULL, "fffc8000.pwm", &pwm_clk), - CLKDEV_CON_DEV_ID(NULL, "ffffc800.pwm", &pwm_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk), - CLKDEV_CON_ID("adc_clk", &tsc_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), -}; - -/* - * The two programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static void __init at91sam9rl_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); -} -#endif - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91sam9rl_gpio[] __initdata = { - { - .id = AT91SAM9RL_ID_PIOA, - .regbase = AT91SAM9RL_BASE_PIOA, - }, { - .id = AT91SAM9RL_ID_PIOB, - .regbase = AT91SAM9RL_BASE_PIOB, - }, { - .id = AT91SAM9RL_ID_PIOC, - .regbase = AT91SAM9RL_BASE_PIOC, - }, { - .id = AT91SAM9RL_ID_PIOD, - .regbase = AT91SAM9RL_BASE_PIOD, - } -}; /* -------------------------------------------------------------------- * AT91SAM9RL processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9rl_map_io(void) -{ - unsigned long sram_size; - - switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) { - case AT91_CIDR_SRAMSIZ_32K: - sram_size = 2 * SZ_16K; - break; - case AT91_CIDR_SRAMSIZ_16K: - default: - sram_size = SZ_16K; - } - - /* Map SRAM */ - at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size); -} - -static void __init at91sam9rl_ioremap_registers(void) -{ - at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); - at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); - at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); - at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX); - at91_pm_set_standby(at91sam9_sdram_standby); -} - static void __init at91sam9rl_initialize(void) { arm_pm_idle = at91sam9_idle; at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); - - /* Register GPIO subsystem */ - at91_gpio_init(at91sam9rl_gpio, 4); -} - -static struct resource rstc_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_RSTC, - .end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9RL_BASE_SDRAMC, - .end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device rstc_device = { - .name = "at91-sam9260-reset", - .resource = rstc_resources, - .num_resources = ARRAY_SIZE(rstc_resources), -}; - -static struct resource shdwc_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_SHDWC, - .end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device shdwc_device = { - .name = "at91-poweroff", - .resource = shdwc_resources, - .num_resources = ARRAY_SIZE(shdwc_resources), -}; - -static void __init at91sam9rl_register_devices(void) -{ - platform_device_register(&rstc_device); - platform_device_register(&shdwc_device); -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 1, /* Parallel IO Controller D */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 5, /* USART 3 */ - 0, /* Multimedia Card Interface */ - 6, /* Two-Wire Interface 0 */ - 6, /* Two-Wire Interface 1 */ - 5, /* Serial Peripheral Interface */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 0, - 0, /* Touch Screen Controller */ - 0, /* DMA Controller */ - 2, /* USB Device High speed port */ - 2, /* LCD Controller */ - 6, /* AC97 Controller */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, /* Advanced Interrupt Controller */ -}; - -static void __init at91sam9rl_init_time(void) -{ - at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); } AT91_SOC_START(at91sam9rl) - .map_io = at91sam9rl_map_io, - .default_irq_priority = at91sam9rl_default_irq_priority, - .extern_irq = (1 << AT91SAM9RL_ID_IRQ0), - .ioremap_registers = at91sam9rl_ioremap_registers, -#if defined(CONFIG_OLD_CLK_AT91) - .register_clocks = at91sam9rl_register_clocks, -#endif - .register_devices = at91sam9rl_register_devices, .init = at91sam9rl_initialize, - .init_time = at91sam9rl_init_time, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9rl_devices.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9rl_devices.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2007 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <linux/fb.h> -#include <video/atmel_lcdc.h> - -#include <mach/at91sam9rl.h> -#include <mach/at91sam9rl_matrix.h> -#include <mach/at91_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> -#include <linux/platform_data/dma-atmel.h> -#include <linux/platform_data/at91_adc.h> - -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -/* -------------------------------------------------------------------- - * HDMAC - AHB DMA Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) -static u64 hdmac_dmamask = DMA_BIT_MASK(32); - -static struct resource hdmac_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_DMA, - .end = AT91SAM9RL_BASE_DMA + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_DMA, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_DMA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at_hdmac_device = { - .name = "at91sam9rl_dma", - .id = -1, - .dev = { - .dma_mask = &hdmac_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = hdmac_resources, - .num_resources = ARRAY_SIZE(hdmac_resources), -}; - -void __init at91_add_device_hdmac(void) -{ - platform_device_register(&at_hdmac_device); -} -#else -void __init at91_add_device_hdmac(void) {} -#endif - -/* -------------------------------------------------------------------- - * USB HS Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE) - -static struct resource usba_udc_resources[] = { - [0] = { - .start = AT91SAM9RL_UDPHS_FIFO, - .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9RL_BASE_UDPHS, - .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_UDPHS, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_UDPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -static struct usba_ep_data usba_udc_ep[] __initdata = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 2, 1, 1), - EP("ep2", 2, 1024, 2, 1, 1), - EP("ep3", 3, 1024, 3, 1, 0), - EP("ep4", 4, 1024, 3, 1, 0), - EP("ep5", 5, 1024, 3, 1, 1), - EP("ep6", 6, 1024, 3, 1, 1), -}; - -#undef EP - -/* - * pdata doesn't have room for any endpoints, so we need to - * append room for the ones we need right after it. - */ -static struct { - struct usba_platform_data pdata; - struct usba_ep_data ep[7]; -} usba_udc_data; - -static struct platform_device at91_usba_udc_device = { - .name = "atmel_usba_udc", - .id = -1, - .dev = { - .platform_data = &usba_udc_data.pdata, - }, - .resource = usba_udc_resources, - .num_resources = ARRAY_SIZE(usba_udc_resources), -}; - -void __init at91_add_device_usba(struct usba_platform_data *data) -{ - /* - * Invalid pins are 0 on AT91, but the usba driver is shared - * with AVR32, which use negative values instead. Once/if - * gpio_is_valid() is ported to AT91, revisit this code. - */ - usba_udc_data.pdata.vbus_pin = -EINVAL; - usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - - if (data && gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - usba_udc_data.pdata.vbus_pin = data->vbus_pin; - } - - /* Pullup pin is handled internally by USB device peripheral */ - - platform_device_register(&at91_usba_udc_device); -} -#else -void __init at91_add_device_usba(struct usba_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct mci_platform_data mmc_data; - -static struct resource mmc_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_MCI, - .end = AT91SAM9RL_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_MCI, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_mmc_device = { - .name = "atmel_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc_data, - }, - .resource = mmc_resources, - .num_resources = ARRAY_SIZE(mmc_resources), -}; - -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) -{ - if (!data) - return; - - if (data->slot[0].bus_width) { - /* input/irq */ - if (gpio_is_valid(data->slot[0].detect_pin)) { - at91_set_gpio_input(data->slot[0].detect_pin, 1); - at91_set_deglitch(data->slot[0].detect_pin, 1); - } - if (gpio_is_valid(data->slot[0].wp_pin)) - at91_set_gpio_input(data->slot[0].wp_pin, 1); - - /* CLK */ - at91_set_A_periph(AT91_PIN_PA2, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA0, 1); - if (data->slot[0].bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); - } - - mmc_data = *data; - platform_device_register(&at91sam9rl_mmc_device); - } -} -#else -void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9RL_BASE_ECC, - .end = AT91SAM9RL_BASE_ECC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device atmel_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* NANDWE */ - - nand_data = *data; - platform_device_register(&atmel_nand_device); -} - -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PA23, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA24, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91sam9rl_twi_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA23, 1); - - at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA24, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9rl_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_TWI0, - .end = AT91SAM9RL_BASE_TWI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_TWI0, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_TWI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_twi_device = { - .name = "i2c-at91sam9g20", - .id = 0, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA23, 1); - - at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA24, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9rl_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_SPI, - .end = AT91SAM9RL_BASE_SPI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_SPI, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_spi_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi_resources, - .num_resources = ARRAY_SIZE(spi_resources), -}; - -static const unsigned spi_standard_cs[4] = { AT91_PIN_PA28, AT91_PIN_PB7, AT91_PIN_PD8, AT91_PIN_PD9 }; - - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - - at91_set_A_periph(AT91_PIN_PA25, 0); /* MISO */ - at91_set_A_periph(AT91_PIN_PA26, 0); /* MOSI */ - at91_set_A_periph(AT91_PIN_PA27, 0); /* SPCK */ - - /* Enable SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else - cs_pin = spi_standard_cs[devices[i].chip_select]; - - if (!gpio_is_valid(cs_pin)) - continue; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - platform_device_register(&at91sam9rl_spi_device); -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) -static u64 ac97_dmamask = DMA_BIT_MASK(32); -static struct ac97c_platform_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_AC97C, - .end = AT91SAM9RL_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_AC97C, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_ac97_device = { - .name = "atmel_ac97c", - .id = 0, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct ac97c_platform_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PD1, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PD2, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PD3, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */ - - /* reset */ - if (gpio_is_valid(data->reset_pin)) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *data; - platform_device_register(&at91sam9rl_ac97_device); -} -#else -void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_pdata lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91SAM9RL_LCDC_BASE, - .end = AT91SAM9RL_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_LCDC, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .name = "at91sam9rl-lcdfb", - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) -{ - if (!data) { - return; - } - - at91_set_B_periph(AT91_PIN_PC1, 0); /* LCDPWR */ - at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDDEN */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDCC */ - at91_set_B_periph(AT91_PIN_PC9, 0); /* LCDD3 */ - at91_set_B_periph(AT91_PIN_PC10, 0); /* LCDD4 */ - at91_set_B_periph(AT91_PIN_PC11, 0); /* LCDD5 */ - at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD6 */ - at91_set_B_periph(AT91_PIN_PC13, 0); /* LCDD7 */ - at91_set_B_periph(AT91_PIN_PC15, 0); /* LCDD11 */ - at91_set_B_periph(AT91_PIN_PC16, 0); /* LCDD12 */ - at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD13 */ - at91_set_B_periph(AT91_PIN_PC18, 0); /* LCDD14 */ - at91_set_B_periph(AT91_PIN_PC19, 0); /* LCDD15 */ - at91_set_B_periph(AT91_PIN_PC20, 0); /* LCDD18 */ - at91_set_B_periph(AT91_PIN_PC21, 0); /* LCDD19 */ - at91_set_B_periph(AT91_PIN_PC22, 0); /* LCDD20 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* LCDD21 */ - at91_set_B_periph(AT91_PIN_PC24, 0); /* LCDD22 */ - at91_set_B_periph(AT91_PIN_PC25, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_TCB0, - .end = AT91SAM9RL_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC0, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC0, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC1, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC1, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC2, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_TC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_tcb_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb_resources, - .num_resources = ARRAY_SIZE(tcb_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91sam9rl_tcb_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * ADC and Touchscreen - * -------------------------------------------------------------------- */ - -#if IS_ENABLED(CONFIG_AT91_ADC) -static struct at91_adc_data adc_data; - -static struct resource adc_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_TSC, - .end = AT91SAM9RL_BASE_TSC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_TSC, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_TSC, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91_adc_device = { - .name = "at91sam9rl-adc", - .id = -1, - .dev = { - .platform_data = &adc_data, - }, - .resource = adc_resources, - .num_resources = ARRAY_SIZE(adc_resources), -}; - -static struct at91_adc_trigger at91_adc_triggers[] = { - [0] = { - .name = "external-rising", - .value = 1, - .is_external = true, - }, - [1] = { - .name = "external-falling", - .value = 2, - .is_external = true, - }, - [2] = { - .name = "external-any", - .value = 3, - .is_external = true, - }, - [3] = { - .name = "continuous", - .value = 6, - .is_external = false, - }, -}; - -void __init at91_add_device_adc(struct at91_adc_data *data) -{ - if (!data) - return; - - if (test_bit(0, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PA17, 0); - if (test_bit(1, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PA18, 0); - if (test_bit(2, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PA19, 0); - if (test_bit(3, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PA20, 0); - if (test_bit(4, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PD6, 0); - if (test_bit(5, &data->channels_used)) - at91_set_A_periph(AT91_PIN_PD7, 0); - - if (data->use_external_triggers) - at91_set_A_periph(AT91_PIN_PB15, 0); - - data->startup_time = 40; - data->trigger_number = 4; - data->trigger_list = at91_adc_triggers; - - adc_data = *data; - platform_device_register(&at91_adc_device); -} -#else -void __init at91_add_device_adc(struct at91_adc_data *data) {} -#endif - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) -static struct platform_device at91sam9rl_rtc_device = { - .name = "at91_rtc", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91sam9rl_rtc_device); -} -#else -static void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91SAM9RL_BASE_RTT, - .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_MEM, - }, { - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device at91sam9rl_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, -}; - -#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) -static void __init at91_add_device_rtt_rtc(void) -{ - at91sam9rl_rtt_device.name = "rtc-at91sam9"; - /* - * The second resource is needed: - * GPBR will serve as the storage for RTC time offset - */ - at91sam9rl_rtt_device.num_resources = 3; - rtt_resources[1].start = AT91SAM9RL_BASE_GPBR + - 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; - rtt_resources[1].end = rtt_resources[1].start + 3; - rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; - rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; -} -#else -static void __init at91_add_device_rtt_rtc(void) -{ - /* Only one resource is needed: RTT not used as RTC */ - at91sam9rl_rtt_device.num_resources = 1; -} -#endif - -static void __init at91_add_device_rtt(void) -{ - at91_add_device_rtt_rtc(); - platform_device_register(&at91sam9rl_rtt_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91SAM9RL_BASE_WDT, - .end = AT91SAM9RL_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91sam9rl_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91sam9rl_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * PWM - * --------------------------------------------------------------------*/ - -#if IS_ENABLED(CONFIG_PWM_ATMEL) -static struct resource pwm_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_PWMC, - .end = AT91SAM9RL_BASE_PWMC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_PWMC, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_PWMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_pwm0_device = { - .name = "at91sam9rl-pwm", - .id = -1, - .resource = pwm_resources, - .num_resources = ARRAY_SIZE(pwm_resources), -}; - -void __init at91_add_device_pwm(u32 mask) -{ - if (mask & (1 << AT91_PWM0)) - at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM0 */ - - if (mask & (1 << AT91_PWM1)) - at91_set_B_periph(AT91_PIN_PB9, 1); /* enable PWM1 */ - - if (mask & (1 << AT91_PWM2)) - at91_set_B_periph(AT91_PIN_PD5, 1); /* enable PWM2 */ - - if (mask & (1 << AT91_PWM3)) - at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */ - - platform_device_register(&at91sam9rl_pwm0_device); -} -#else -void __init at91_add_device_pwm(u32 mask) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_SSC0, - .end = AT91SAM9RL_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_SSC0, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_ssc0_device = { - .name = "at91rm9200_ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PC0, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PC1, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PA15, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PA16, 1); - if (pins & ATMEL_SSC_RK) - at91_set_B_periph(AT91_PIN_PA10, 1); - if (pins & ATMEL_SSC_RF) - at91_set_B_periph(AT91_PIN_PA22, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_SSC1, - .end = AT91SAM9RL_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_SSC1, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9rl_ssc1_device = { - .name = "at91rm9200_ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_B_periph(AT91_PIN_PA29, 1); - if (pins & ATMEL_SSC_TK) - at91_set_B_periph(AT91_PIN_PA30, 1); - if (pins & ATMEL_SSC_TD) - at91_set_B_periph(AT91_PIN_PA13, 1); - if (pins & ATMEL_SSC_RD) - at91_set_B_periph(AT91_PIN_PA14, 1); - if (pins & ATMEL_SSC_RK) - at91_set_B_periph(AT91_PIN_PA9, 1); - if (pins & ATMEL_SSC_RF) - at91_set_B_periph(AT91_PIN_PA8, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91SAM9RL_ID_SSC0: - pdev = &at91sam9rl_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91SAM9RL_ID_SSC1: - pdev = &at91sam9rl_ssc1_device; - configure_ssc1_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_DBGU, - .end = AT91SAM9RL_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91_ID_SYS, - .end = NR_IRQS_LEGACY + AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9rl_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA21, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA22, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_US0, - .end = AT91SAM9RL_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_US0, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9rl_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */ - if (pins & ATMEL_UART_DSR) - at91_set_A_periph(AT91_PIN_PD14, 0); /* DSR0 */ - if (pins & ATMEL_UART_DTR) - at91_set_A_periph(AT91_PIN_PD15, 0); /* DTR0 */ - if (pins & ATMEL_UART_DCD) - at91_set_A_periph(AT91_PIN_PD16, 0); /* DCD0 */ - if (pins & ATMEL_UART_RI) - at91_set_A_periph(AT91_PIN_PD17, 0); /* RI0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_US1, - .end = AT91SAM9RL_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_US1, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9rl_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PA18, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PA19, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_US2, - .end = AT91SAM9RL_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_US2, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9rl_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA29, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA30, 0); /* CTS2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91SAM9RL_BASE_US3, - .end = AT91SAM9RL_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9RL_ID_US3, - .end = NR_IRQS_LEGACY + AT91SAM9RL_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart3_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91sam9rl_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .dma_mask = &uart3_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart3_data, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD4, 0); /* RTS3 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91sam9rl_dbgu_device; - configure_dbgu_pins(); - break; - case AT91SAM9RL_ID_US0: - pdev = &at91sam9rl_uart0_device; - configure_usart0_pins(pins); - break; - case AT91SAM9RL_ID_US1: - pdev = &at91sam9rl_uart1_device; - configure_usart1_pins(pins); - break; - case AT91SAM9RL_ID_US2: - pdev = &at91sam9rl_uart2_device; - configure_usart2_pins(pins); - break; - case AT91SAM9RL_ID_US3: - pdev = &at91sam9rl_uart3_device; - configure_usart3_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_hdmac(); - at91_add_device_rtc(); - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9x5.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91sam9x5.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91sam9x5.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:9 @ * Licensed under GPLv2 or later. */ -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/clk/at91_pmc.h> +#include <asm/system_misc.h> +#include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <mach/at91sam9x5.h> -#include <mach/cpu.h> - -#include "board.h" #include "soc.h" #include "generic.h" -#include "sam9_smc.h" - -#if defined(CONFIG_OLD_CLK_AT91) -#include "clock.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioAB_clk = { - .name = "pioAB_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_PIOAB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioCD_clk = { - .name = "pioCD_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_PIOCD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk smd_clk = { - .name = "smd_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_SMD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_USART0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_USART1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_USART2, - .type = CLK_TYPE_PERIPHERAL, -}; -/* USART3 clock - Only for sam9g25/sam9x25 */ -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_USART3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi0_clk = { - .name = "twi0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_TWI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi1_clk = { - .name = "twi1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_TWI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi2_clk = { - .name = "twi2_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_TWI2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uart0_clk = { - .name = "uart0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_UART0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uart1_clk = { - .name = "uart1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_UART1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb0_clk = { - .name = "tcb0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_PWM, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_op_clk = { - .name = "adc_op_clk", - .type = CLK_TYPE_PERIPHERAL, - .rate_hz = 5000000, -}; -static struct clk dma0_clk = { - .name = "dma0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma1_clk = { - .name = "dma1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_DMA1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uhphs_clk = { - .name = "uhphs", - .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */ -static struct clk macb0_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0, - .type = CLK_TYPE_PERIPHERAL, -}; -/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */ -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -/* isi clock - Only for sam9g25 */ -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -/* emac1 clock - Only for sam9x25 */ -static struct clk macb1_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc_clk = { - .name = "ssc_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_SSC, - .type = CLK_TYPE_PERIPHERAL, -}; -/* can0 clock - Only for sam9x35 */ -static struct clk can0_clk = { - .name = "can0_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_CAN0, - .type = CLK_TYPE_PERIPHERAL, -}; -/* can1 clock - Only for sam9x35 */ -static struct clk can1_clk = { - .name = "can1_clk", - .pmc_mask = 1 << AT91SAM9X5_ID_CAN1, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioAB_clk, - &pioCD_clk, - &smd_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &twi0_clk, - &twi1_clk, - &twi2_clk, - &mmc0_clk, - &spi0_clk, - &spi1_clk, - &uart0_clk, - &uart1_clk, - &tcb0_clk, - &pwm_clk, - &adc_clk, - &adc_op_clk, - &dma0_clk, - &dma1_clk, - &uhphs_clk, - &udphs_clk, - &mmc1_clk, - &ssc_clk, - // irq0 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), - CLKDEV_CON_DEV_ID("usart", "f8040000.serial", &uart0_clk), - CLKDEV_CON_DEV_ID("usart", "f8044000.serial", &uart1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), - CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk), - CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f0000000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), - /* additional fake clock for macb_hclk */ - CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), - CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), - CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk), - CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk), - CLKDEV_CON_DEV_ID(NULL, "f8034000.pwm", &pwm_clk), -}; - -/* - * The two programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static void __init at91sam9x5_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - - if (cpu_is_at91sam9g25() - || cpu_is_at91sam9x25()) - clk_register(&usart3_clk); - - if (cpu_is_at91sam9g25() - || cpu_is_at91sam9x25() - || cpu_is_at91sam9g35() - || cpu_is_at91sam9x35()) - clk_register(&macb0_clk); - - if (cpu_is_at91sam9g15() - || cpu_is_at91sam9g35() - || cpu_is_at91sam9x35()) - clk_register(&lcdc_clk); - - if (cpu_is_at91sam9g25()) - clk_register(&isi_clk); - - if (cpu_is_at91sam9x25()) - clk_register(&macb1_clk); - - if (cpu_is_at91sam9x25() - || cpu_is_at91sam9x35()) { - clk_register(&can0_clk); - clk_register(&can1_clk); - } - - clk_register(&pck0); - clk_register(&pck1); -} -#else -#define at91sam9x5_register_clocks NULL -#endif /* -------------------------------------------------------------------- * AT91SAM9x5 processor initialization * -------------------------------------------------------------------- */ -static void __init at91sam9x5_map_io(void) -{ - at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); -} - static void __init at91sam9x5_initialize(void) { at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:29 @ static void __init at91sam9x5_initialize * -------------------------------------------------------------------- */ AT91_SOC_START(at91sam9x5) - .map_io = at91sam9x5_map_io, - .register_clocks = at91sam9x5_register_clocks, .init = at91sam9x5_initialize, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91_tc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91_tc.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/at91_tc.h - * - * Copyright (C) SAN People - * - * Timer/Counter Unit (TC) registers. - * Based on AT91RM9200 datasheet revision E. - * - * 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. - */ - -#ifndef AT91_TC_H -#define AT91_TC_H - -#define AT91_TC_BCR 0xc0 /* TC Block Control Register */ -#define AT91_TC_SYNC (1 << 0) /* Synchro Command */ - -#define AT91_TC_BMR 0xc4 /* TC Block Mode Register */ -#define AT91_TC_TC0XC0S (3 << 0) /* External Clock Signal 0 Selection */ -#define AT91_TC_TC0XC0S_TCLK0 (0 << 0) -#define AT91_TC_TC0XC0S_NONE (1 << 0) -#define AT91_TC_TC0XC0S_TIOA1 (2 << 0) -#define AT91_TC_TC0XC0S_TIOA2 (3 << 0) -#define AT91_TC_TC1XC1S (3 << 2) /* External Clock Signal 1 Selection */ -#define AT91_TC_TC1XC1S_TCLK1 (0 << 2) -#define AT91_TC_TC1XC1S_NONE (1 << 2) -#define AT91_TC_TC1XC1S_TIOA0 (2 << 2) -#define AT91_TC_TC1XC1S_TIOA2 (3 << 2) -#define AT91_TC_TC2XC2S (3 << 4) /* External Clock Signal 2 Selection */ -#define AT91_TC_TC2XC2S_TCLK2 (0 << 4) -#define AT91_TC_TC2XC2S_NONE (1 << 4) -#define AT91_TC_TC2XC2S_TIOA0 (2 << 4) -#define AT91_TC_TC2XC2S_TIOA1 (3 << 4) - - -#define AT91_TC_CCR 0x00 /* Channel Control Register */ -#define AT91_TC_CLKEN (1 << 0) /* Counter Clock Enable Command */ -#define AT91_TC_CLKDIS (1 << 1) /* Counter CLock Disable Command */ -#define AT91_TC_SWTRG (1 << 2) /* Software Trigger Command */ - -#define AT91_TC_CMR 0x04 /* Channel Mode Register */ -#define AT91_TC_TCCLKS (7 << 0) /* Capture/Waveform Mode: Clock Selection */ -#define AT91_TC_TIMER_CLOCK1 (0 << 0) -#define AT91_TC_TIMER_CLOCK2 (1 << 0) -#define AT91_TC_TIMER_CLOCK3 (2 << 0) -#define AT91_TC_TIMER_CLOCK4 (3 << 0) -#define AT91_TC_TIMER_CLOCK5 (4 << 0) -#define AT91_TC_XC0 (5 << 0) -#define AT91_TC_XC1 (6 << 0) -#define AT91_TC_XC2 (7 << 0) -#define AT91_TC_CLKI (1 << 3) /* Capture/Waveform Mode: Clock Invert */ -#define AT91_TC_BURST (3 << 4) /* Capture/Waveform Mode: Burst Signal Selection */ -#define AT91_TC_LDBSTOP (1 << 6) /* Capture Mode: Counter Clock Stopped with TB Loading */ -#define AT91_TC_LDBDIS (1 << 7) /* Capture Mode: Counter Clock Disable with RB Loading */ -#define AT91_TC_ETRGEDG (3 << 8) /* Capture Mode: External Trigger Edge Selection */ -#define AT91_TC_ABETRG (1 << 10) /* Capture Mode: TIOA or TIOB External Trigger Selection */ -#define AT91_TC_CPCTRG (1 << 14) /* Capture Mode: RC Compare Trigger Enable */ -#define AT91_TC_WAVE (1 << 15) /* Capture/Waveform mode */ -#define AT91_TC_LDRA (3 << 16) /* Capture Mode: RA Loading Selection */ -#define AT91_TC_LDRB (3 << 18) /* Capture Mode: RB Loading Selection */ - -#define AT91_TC_CPCSTOP (1 << 6) /* Waveform Mode: Counter Clock Stopped with RC Compare */ -#define AT91_TC_CPCDIS (1 << 7) /* Waveform Mode: Counter Clock Disable with RC Compare */ -#define AT91_TC_EEVTEDG (3 << 8) /* Waveform Mode: External Event Edge Selection */ -#define AT91_TC_EEVTEDG_NONE (0 << 8) -#define AT91_TC_EEVTEDG_RISING (1 << 8) -#define AT91_TC_EEVTEDG_FALLING (2 << 8) -#define AT91_TC_EEVTEDG_BOTH (3 << 8) -#define AT91_TC_EEVT (3 << 10) /* Waveform Mode: External Event Selection */ -#define AT91_TC_EEVT_TIOB (0 << 10) -#define AT91_TC_EEVT_XC0 (1 << 10) -#define AT91_TC_EEVT_XC1 (2 << 10) -#define AT91_TC_EEVT_XC2 (3 << 10) -#define AT91_TC_ENETRG (1 << 12) /* Waveform Mode: External Event Trigger Enable */ -#define AT91_TC_WAVESEL (3 << 13) /* Waveform Mode: Waveform Selection */ -#define AT91_TC_WAVESEL_UP (0 << 13) -#define AT91_TC_WAVESEL_UP_AUTO (2 << 13) -#define AT91_TC_WAVESEL_UPDOWN (1 << 13) -#define AT91_TC_WAVESEL_UPDOWN_AUTO (3 << 13) -#define AT91_TC_ACPA (3 << 16) /* Waveform Mode: RA Compare Effect on TIOA */ -#define AT91_TC_ACPA_NONE (0 << 16) -#define AT91_TC_ACPA_SET (1 << 16) -#define AT91_TC_ACPA_CLEAR (2 << 16) -#define AT91_TC_ACPA_TOGGLE (3 << 16) -#define AT91_TC_ACPC (3 << 18) /* Waveform Mode: RC Compre Effect on TIOA */ -#define AT91_TC_ACPC_NONE (0 << 18) -#define AT91_TC_ACPC_SET (1 << 18) -#define AT91_TC_ACPC_CLEAR (2 << 18) -#define AT91_TC_ACPC_TOGGLE (3 << 18) -#define AT91_TC_AEEVT (3 << 20) /* Waveform Mode: External Event Effect on TIOA */ -#define AT91_TC_AEEVT_NONE (0 << 20) -#define AT91_TC_AEEVT_SET (1 << 20) -#define AT91_TC_AEEVT_CLEAR (2 << 20) -#define AT91_TC_AEEVT_TOGGLE (3 << 20) -#define AT91_TC_ASWTRG (3 << 22) /* Waveform Mode: Software Trigger Effect on TIOA */ -#define AT91_TC_ASWTRG_NONE (0 << 22) -#define AT91_TC_ASWTRG_SET (1 << 22) -#define AT91_TC_ASWTRG_CLEAR (2 << 22) -#define AT91_TC_ASWTRG_TOGGLE (3 << 22) -#define AT91_TC_BCPB (3 << 24) /* Waveform Mode: RB Compare Effect on TIOB */ -#define AT91_TC_BCPB_NONE (0 << 24) -#define AT91_TC_BCPB_SET (1 << 24) -#define AT91_TC_BCPB_CLEAR (2 << 24) -#define AT91_TC_BCPB_TOGGLE (3 << 24) -#define AT91_TC_BCPC (3 << 26) /* Waveform Mode: RC Compare Effect on TIOB */ -#define AT91_TC_BCPC_NONE (0 << 26) -#define AT91_TC_BCPC_SET (1 << 26) -#define AT91_TC_BCPC_CLEAR (2 << 26) -#define AT91_TC_BCPC_TOGGLE (3 << 26) -#define AT91_TC_BEEVT (3 << 28) /* Waveform Mode: External Event Effect on TIOB */ -#define AT91_TC_BEEVT_NONE (0 << 28) -#define AT91_TC_BEEVT_SET (1 << 28) -#define AT91_TC_BEEVT_CLEAR (2 << 28) -#define AT91_TC_BEEVT_TOGGLE (3 << 28) -#define AT91_TC_BSWTRG (3 << 30) /* Waveform Mode: Software Trigger Effect on TIOB */ -#define AT91_TC_BSWTRG_NONE (0 << 30) -#define AT91_TC_BSWTRG_SET (1 << 30) -#define AT91_TC_BSWTRG_CLEAR (2 << 30) -#define AT91_TC_BSWTRG_TOGGLE (3 << 30) - -#define AT91_TC_CV 0x10 /* Counter Value */ -#define AT91_TC_RA 0x14 /* Register A */ -#define AT91_TC_RB 0x18 /* Register B */ -#define AT91_TC_RC 0x1c /* Register C */ - -#define AT91_TC_SR 0x20 /* Status Register */ -#define AT91_TC_COVFS (1 << 0) /* Counter Overflow Status */ -#define AT91_TC_LOVRS (1 << 1) /* Load Overrun Status */ -#define AT91_TC_CPAS (1 << 2) /* RA Compare Status */ -#define AT91_TC_CPBS (1 << 3) /* RB Compare Status */ -#define AT91_TC_CPCS (1 << 4) /* RC Compare Status */ -#define AT91_TC_LDRAS (1 << 5) /* RA Loading Status */ -#define AT91_TC_LDRBS (1 << 6) /* RB Loading Status */ -#define AT91_TC_ETRGS (1 << 7) /* External Trigger Status */ -#define AT91_TC_CLKSTA (1 << 16) /* Clock Enabling Status */ -#define AT91_TC_MTIOA (1 << 17) /* TIOA Mirror */ -#define AT91_TC_MTIOB (1 << 18) /* TIOB Mirror */ - -#define AT91_TC_IER 0x24 /* Interrupt Enable Register */ -#define AT91_TC_IDR 0x28 /* Interrupt Disable Register */ -#define AT91_TC_IMR 0x2c /* Interrupt Mask Register */ - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91_vdec.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91_vdec.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Video Decoder (VDEC) - System peripherals registers. + * + * Copyright (C) 2009 Hantro Products Oy. + * + * Based on SAMA5D4 datasheet. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef AT91_VDEC_H +#define AT91_VDEC_H + +#define VDEC_IDR 0x00 /* ID Register (read-only) */ +#define VDEC_IDR_BUILD_VER 0xf /* Build Version is 0x02. */ +#define VDEC_IDR_MINOR_VER (0xff << 4) /* Minor Version is 0x88. */ +#define VDEC_IDR_MAJOR_VER (0xf << 12) /* Major Version is 0x08. */ +#define VDEC_IDR_PROD_ID (0xffff << 16) /* Product ID is 0x6731. */ + +#define VDEC_DIR 0x04 /* Decoder Interrupt Register */ +#define VDEC_DIR_DE 1 /* 1: Enable decoder; 0: Disable decoder. */ +#define VDEC_DIR_ID 0x10 /* 1: Disable interrupts for decoder; 0: Enable interrupts. */ +#define VDEC_DIR_ABORT 0x20 +#define VDEC_DIR_ISET 0x100 /* Decoder Interrupt Set. 0: Clears the Decoder Interrupt. */ + +#define VDEC_PPIR 0xF0 /* Post Processor Interrupt Register */ +#define VDEC_PPIR_PPE 1 /* 1: Enable post-processor; 0: Disable post-processor */ +#define VDEC_PPIR_ID 0x10 /* 1: Disable interrupts for post-processor; 0: Enable interrupts. */ +#define VDEC_PPIR_ISET 0x100 /* Post-processor Interrupt Set. 0: Clears the post-processor Interrupt. */ + +#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91x40.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91x40.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91x40.c - * - * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> - * Copyright (C) 2005 SAN People - * - * 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. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <asm/proc-fns.h> -#include <asm/system_misc.h> -#include <asm/mach/arch.h> -#include <mach/at91x40.h> -#include <mach/at91_st.h> -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "generic.h" - -/* - * Export the clock functions for the AT91X40. Some external code common - * to all AT91 family parts relys on this, like the gpio and serial support. - */ -int clk_enable(struct clk *clk) -{ - return 0; -} - -void clk_disable(struct clk *clk) -{ -} - -unsigned long clk_get_rate(struct clk *clk) -{ - return AT91X40_MASTER_CLOCK; -} - -static void at91x40_idle(void) -{ - /* - * Disable the processor clock. The processor will be automatically - * re-enabled by an interrupt or by a reset. - */ - __raw_writel(AT91_PS_CR_CPU, AT91_IO_P2V(AT91_PS_CR)); - cpu_do_idle(); -} - -void __init at91x40_initialize(unsigned long main_clock) -{ - arm_pm_idle = at91x40_idle; -} - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 0, /* System Peripherals */ - 0, /* USART 0 */ - 0, /* USART 1 */ - 2, /* Timer Counter 0 */ - 2, /* Timer Counter 1 */ - 2, /* Timer Counter 2 */ - 0, /* Watchdog timer */ - 0, /* Parallel IO Controller A */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* Reserved */ - 0, /* External IRQ0 */ - 0, /* External IRQ1 */ - 0, /* External IRQ2 */ -}; - -void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - u32 extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) - | (1 << AT91X40_ID_IRQ2); - if (!priority) - priority = at91x40_default_irq_priority; - - at91_aic_init(priority, extern_irq); -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/at91x40_time.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/at91x40_time.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/at91x40_time.c - * - * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> - * - * 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 - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/time.h> -#include <linux/io.h> -#include <mach/hardware.h> -#include <mach/at91x40.h> -#include <asm/mach/time.h> - -#include "at91_tc.h" - -#define at91_tc_read(field) \ - __raw_readl(AT91_IO_P2V(AT91_TC) + field) - -#define at91_tc_write(field, value) \ - __raw_writel(value, AT91_IO_P2V(AT91_TC) + field) - -/* - * 3 counter/timer units present. - */ -#define AT91_TC_CLK0BASE 0 -#define AT91_TC_CLK1BASE 0x40 -#define AT91_TC_CLK2BASE 0x80 - -static u32 at91x40_gettimeoffset(void) -{ - return (at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / - (AT91X40_MASTER_CLOCK / 128)) * 1000; -} - -static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) -{ - at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_SR); - timer_tick(); - return IRQ_HANDLED; -} - -static struct irqaction at91x40_timer_irq = { - .name = "at91_tick", - .flags = IRQF_TIMER, - .handler = at91x40_timer_interrupt -}; - -void __init at91x40_timer_init(void) -{ - unsigned int v; - - arch_gettimeoffset = at91x40_gettimeoffset; - - at91_tc_write(AT91_TC_BCR, 0); - v = at91_tc_read(AT91_TC_BMR); - v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE; - at91_tc_write(AT91_TC_BMR, v); - - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); - - setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq); - - at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-1arm.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-1arm.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-1arm.c - * - * Copyright (C) 2005 SAN People - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - -static void __init onearm_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata onearm_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata onearm_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata onearm_udc_data = { - .vbus_pin = AT91_PIN_PC2, - .pullup_pin = AT91_PIN_PC3, -}; - -static void __init onearm_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&onearm_eth_data); - /* USB Host */ - at91_add_device_usbh(&onearm_usbh_data); - /* USB Device */ - at91_add_device_udc(&onearm_udc_data); -} - -MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") - /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = onearm_init_early, - .init_irq = at91_init_irq_default, - .init_machine = onearm_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-afeb-9260v1.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-afeb-9260v1.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-afeb-9260v1.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * Copyright (C) 2008 Sergey Lapin - * - * A custom board designed as open hardware; PCBs and various information - * is available at http://groups.google.com/group/arm9fpga-evolution-board/ - * Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/clk.h> -#include <linux/dma-mapping.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init afeb9260_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata afeb9260_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata afeb9260_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - - -/* - * SPI devices. - */ -static struct spi_board_info afeb9260_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata afeb9260_macb_data = { - .phy_irq_pin = AT91_PIN_PA9, - .is_rmii = 0, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata afeb9260_nand_partition[] = { - { - .name = "bootloader", - .offset = 0, - .size = (640 * SZ_1K), - }, - { - .name = "kernel", - .offset = MTDPART_OFS_NXTBLK, - .size = SZ_2M, - }, - { - .name = "rootfs", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata afeb9260_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .bus_width_16 = 0, - .ecc_mode = NAND_ECC_SOFT, - .parts = afeb9260_nand_partition, - .num_parts = ARRAY_SIZE(afeb9260_nand_partition), - .det_pin = -EINVAL, -}; - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata afeb9260_mci0_data = { - .slot[1] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC9, - .wp_pin = AT91_PIN_PC4, - }, -}; - - - -static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { - { - I2C_BOARD_INFO("tlv320aic23", 0x1a), - }, { - I2C_BOARD_INFO("fm3130", 0x68), - }, { - I2C_BOARD_INFO("24c64", 0x50), - }, -}; - -/* - * IDE (CF True IDE mode) - */ -static struct at91_cf_data afeb9260_cf_data = { - .chipselect = 4, - .irq_pin = AT91_PIN_PA6, - .det_pin = -EINVAL, - .vcc_pin = -EINVAL, - .rst_pin = AT91_PIN_PA7, - .flags = AT91_CF_TRUE_IDE, -}; - -static void __init afeb9260_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&afeb9260_usbh_data); - /* USB Device */ - at91_add_device_udc(&afeb9260_udc_data); - /* SPI */ - at91_add_device_spi(afeb9260_spi_devices, - ARRAY_SIZE(afeb9260_spi_devices)); - /* NAND */ - at91_add_device_nand(&afeb9260_nand_data); - /* Ethernet */ - at91_add_device_eth(&afeb9260_macb_data); - - /* Standard function's pin assignments are not - * appropriate for us and generic code provide - * no API to configure these pins any other way */ - at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */ - /* MMC */ - at91_add_device_mci(0, &afeb9260_mci0_data); - /* I2C */ - at91_add_device_i2c(afeb9260_i2c_devices, - ARRAY_SIZE(afeb9260_i2c_devices)); - /* Audio */ - at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); - /* IDE */ - at91_add_device_cf(&afeb9260_cf_data); -} - -MACHINE_START(AFEB9260, "Custom afeb9260 board") - /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = afeb9260_init_early, - .init_irq = at91_init_irq_default, - .init_machine = afeb9260_board_init, -MACHINE_END - Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-cam60.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-cam60.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * KwikByte CAM60 (KB9260) - * - * based on board-sam9260ek.c - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/flash.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91sam9_smc.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init cam60_init_early(void) -{ - /* Initialize processor: 10 MHz crystal */ - at91_initialize(10000000); -} - -/* - * USB Host - */ -static struct at91_usbh_data __initdata cam60_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - - -/* - * SPI devices. - */ -#if defined(CONFIG_MTD_DATAFLASH) -static struct mtd_partition cam60_spi_partitions[] = { - { - .name = "BOOT1", - .offset = 0, - .size = 4 * 1056, - }, - { - .name = "BOOT2", - .offset = MTDPART_OFS_NXTBLK, - .size = 256 * 1056, - }, - { - .name = "kernel", - .offset = MTDPART_OFS_NXTBLK, - .size = 2222 * 1056, - }, - { - .name = "file system", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct flash_platform_data cam60_spi_flash_platform_data = { - .name = "spi_flash", - .parts = cam60_spi_partitions, - .nr_parts = ARRAY_SIZE(cam60_spi_partitions) -}; -#endif - -static struct spi_board_info cam60_spi_devices[] __initdata = { -#if defined(CONFIG_MTD_DATAFLASH) - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - .platform_data = &cam60_spi_flash_platform_data - }, -#endif -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data cam60_macb_data __initdata = { - .phy_irq_pin = AT91_PIN_PB5, - .is_rmii = 0, -}; - - -/* - * NAND Flash - */ -static struct mtd_partition __initdata cam60_nand_partition[] = { - { - .name = "nand_fs", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata cam60_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PA9, - .enable_pin = AT91_PIN_PA7, - .ecc_mode = NAND_ECC_SOFT, - .parts = cam60_nand_partition, - .num_parts = ARRAY_SIZE(cam60_nand_partition), -}; - -static struct sam9_smc_config __initdata cam60_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 2, -}; - -static void __init cam60_add_device_nand(void) -{ - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &cam60_nand_smc_config); - - at91_add_device_nand(&cam60_nand_data); -} - - -static void __init cam60_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - /* SPI */ - at91_add_device_spi(cam60_spi_devices, ARRAY_SIZE(cam60_spi_devices)); - /* Ethernet */ - at91_add_device_eth(&cam60_macb_data); - /* USB Host */ - /* enable USB power supply circuit */ - at91_set_gpio_output(AT91_PIN_PB18, 1); - at91_add_device_usbh(&cam60_usbh_data); - /* NAND */ - cam60_add_device_nand(); -} - -MACHINE_START(CAM60, "KwikByte CAM60") - /* Maintainer: KwikByte */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = cam60_init_early, - .init_irq = at91_init_irq_default, - .init_machine = cam60_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-carmeva.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-carmeva.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-carmeva.c - * - * Copyright (c) 2005 Peer Georgi - * Conitec Datasystems - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init carmeva_init_early(void) -{ - /* Initialize processor: 20.000 MHz crystal */ - at91_initialize(20000000); -} - -static struct macb_platform_data __initdata carmeva_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata carmeva_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata carmeva_udc_data = { - .vbus_pin = AT91_PIN_PD12, - .pullup_pin = AT91_PIN_PD9, -}; - -/* FIXME: user dependent */ -// static struct at91_cf_data __initdata carmeva_cf_data = { -// .det_pin = AT91_PIN_PB0, -// .rst_pin = AT91_PIN_PC5, - // .irq_pin = -EINVAL, - // .vcc_pin = -EINVAL, -// }; - -static struct mci_platform_data __initdata carmeva_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PB10, - .wp_pin = AT91_PIN_PC14, - }, -}; - -static struct spi_board_info carmeva_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 10 * 1000 * 1000, - }, - { /* User accessible spi - cs1 (250KHz) */ - .modalias = "spi-cs1", - .chip_select = 1, - .max_speed_hz = 250 * 1000, - }, - { /* User accessible spi - cs2 (1MHz) */ - .modalias = "spi-cs2", - .chip_select = 2, - .max_speed_hz = 1 * 1000 * 1000, - }, - { /* User accessible spi - cs3 (10MHz) */ - .modalias = "spi-cs3", - .chip_select = 3, - .max_speed_hz = 10 * 1000 * 1000, - }, -}; - -static struct gpio_led carmeva_leds[] = { - { /* "user led 1", LED9 */ - .name = "led9", - .gpio = AT91_PIN_PA21, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* "user led 2", LED10 */ - .name = "led10", - .gpio = AT91_PIN_PA25, - .active_low = 1, - }, - { /* "user led 3", LED11 */ - .name = "led11", - .gpio = AT91_PIN_PA26, - .active_low = 1, - }, - { /* "user led 4", LED12 */ - .name = "led12", - .gpio = AT91_PIN_PA18, - .active_low = 1, - } -}; - -static void __init carmeva_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&carmeva_eth_data); - /* USB Host */ - at91_add_device_usbh(&carmeva_usbh_data); - /* USB Device */ - at91_add_device_udc(&carmeva_udc_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* SPI */ - at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices)); - /* Compact Flash */ -// at91_add_device_cf(&carmeva_cf_data); - /* MMC */ - at91_add_device_mci(0, &carmeva_mci0_data); - /* LEDs */ - at91_gpio_leds(carmeva_leds, ARRAY_SIZE(carmeva_leds)); -} - -MACHINE_START(CARMEVA, "Carmeva") - /* Maintainer: Conitec Datasystems */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = carmeva_init_early, - .init_irq = at91_init_irq_default, - .init_machine = carmeva_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-cpu9krea.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-cpu9krea.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-cpu9krea.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * Copyright (C) 2009 Eric Benard - eric@eukrea.com - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/mtd/physmap.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> -#include <mach/at91sam9260_matrix.h> -#include <mach/at91_matrix.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - -static void __init cpu9krea_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata cpu9krea_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata cpu9krea_udc_data = { - .vbus_pin = AT91_PIN_PC8, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata cpu9krea_macb_data = { - .phy_irq_pin = -EINVAL, - .is_rmii = 1, -}; - -/* - * NAND flash - */ -static struct atmel_nand_data __initdata cpu9krea_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .bus_width_16 = 0, - .det_pin = -EINVAL, - .ecc_mode = NAND_ECC_SOFT, -}; - -#ifdef CONFIG_MACH_CPU9260 -static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 2, -}; -#else -static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 3, -}; -#endif - -static void __init cpu9krea_add_device_nand(void) -{ - sam9_smc_configure(0, 3, &cpu9krea_nand_smc_config); - at91_add_device_nand(&cpu9krea_nand_data); -} - -/* - * NOR flash - */ -static struct physmap_flash_data cpuat9260_nor_data = { - .width = 2, -}; - -#define NOR_BASE AT91_CHIPSELECT_0 -#define NOR_SIZE SZ_64M - -static struct resource nor_flash_resources[] = { - { - .start = NOR_BASE, - .end = NOR_BASE + NOR_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device cpu9krea_nor_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &cpuat9260_nor_data, - }, - .resource = nor_flash_resources, - .num_resources = ARRAY_SIZE(nor_flash_resources), -}; - -#ifdef CONFIG_MACH_CPU9260 -static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 10, - .nrd_pulse = 10, - .ncs_write_pulse = 6, - .nwe_pulse = 6, - - .read_cycle = 12, - .write_cycle = 8, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE - | AT91_SMC_DBW_16, - .tdf_cycles = 2, -}; -#else -static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 13, - .nrd_pulse = 13, - .ncs_write_pulse = 8, - .nwe_pulse = 8, - - .read_cycle = 15, - .write_cycle = 10, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE - | AT91_SMC_DBW_16, - .tdf_cycles = 2, -}; -#endif - -static __init void cpu9krea_add_device_nor(void) -{ - unsigned long csa; - - csa = at91_matrix_read(AT91_MATRIX_EBICSA); - at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); - - /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config); - - platform_device_register(&cpu9krea_nor_flash); -} - -/* - * LEDs - */ -static struct gpio_led cpu9krea_leds[] = { - { /* LED1 */ - .name = "LED1", - .gpio = AT91_PIN_PC11, - .active_low = 1, - .default_trigger = "timer", - }, - { /* LED2 */ - .name = "LED2", - .gpio = AT91_PIN_PC12, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* LED3 */ - .name = "LED3", - .gpio = AT91_PIN_PC7, - .active_low = 1, - .default_trigger = "none", - }, - { /* LED4 */ - .name = "LED4", - .gpio = AT91_PIN_PC9, - .active_low = 1, - .default_trigger = "none", - } -}; - -static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = { - { - I2C_BOARD_INFO("ds1339", 0x68), - }, -}; - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button cpu9krea_buttons[] = { - { - .gpio = AT91_PIN_PC3, - .code = BTN_0, - .desc = "BP1", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB20, - .code = BTN_1, - .desc = "BP2", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data cpu9krea_button_data = { - .buttons = cpu9krea_buttons, - .nbuttons = ARRAY_SIZE(cpu9krea_buttons), -}; - -static struct platform_device cpu9krea_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &cpu9krea_button_data, - } -}; - -static void __init cpu9krea_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */ - at91_set_deglitch(AT91_PIN_PC3, 1); - at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */ - at91_set_deglitch(AT91_PIN_PB20, 1); - - platform_device_register(&cpu9krea_button_device); -} -#else -static void __init cpu9krea_add_device_buttons(void) -{ -} -#endif - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata cpu9krea_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PA29, - .wp_pin = -EINVAL, - }, -}; - -static void __init cpu9krea_board_init(void) -{ - at91_register_devices(); - - /* NOR */ - cpu9krea_add_device_nor(); - /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | - ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART3 on ttyS4. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US3, 4, 0); - - /* USART4 on ttyS5. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - - /* USART5 on ttyS6. (Rx, Tx) */ - at91_register_uart(AT91SAM9260_ID_US5, 6, 0); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&cpu9krea_usbh_data); - /* USB Device */ - at91_add_device_udc(&cpu9krea_udc_data); - /* NAND */ - cpu9krea_add_device_nand(); - /* Ethernet */ - at91_add_device_eth(&cpu9krea_macb_data); - /* MMC */ - at91_add_device_mci(0, &cpu9krea_mci0_data); - /* I2C */ - at91_add_device_i2c(cpu9krea_i2c_devices, - ARRAY_SIZE(cpu9krea_i2c_devices)); - /* LEDs */ - at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds)); - /* Push Buttons */ - cpu9krea_add_device_buttons(); -} - -#ifdef CONFIG_MACH_CPU9260 -MACHINE_START(CPUAT9260, "Eukrea CPU9260") -#else -MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") -#endif - /* Maintainer: Eric Benard - EUKREA Electromatique */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = cpu9krea_init_early, - .init_irq = at91_init_irq_default, - .init_machine = cpu9krea_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-cpuat91.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-cpuat91.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-cpuat91.c - * - * Copyright (C) 2009 Eric Benard - eric@eukrea.com - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/plat-ram.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static struct gpio_led cpuat91_leds[] = { - { - .name = "led1", - .default_trigger = "heartbeat", - .active_low = 1, - .gpio = AT91_PIN_PC0, - }, -}; - -static void __init cpuat91_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata cpuat91_eth_data = { - .phy_irq_pin = -EINVAL, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata cpuat91_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata cpuat91_udc_data = { - .vbus_pin = AT91_PIN_PC15, - .pullup_pin = AT91_PIN_PC14, -}; - -static struct mci_platform_data __initdata cpuat91_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC2, - .wp_pin = -EINVAL, - }, -}; - -static struct physmap_flash_data cpuat91_flash_data = { - .width = 2, -}; - -static struct resource cpuat91_flash_resource = { - .start = AT91_CHIPSELECT_0, - .end = AT91_CHIPSELECT_0 + SZ_16M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device cpuat91_norflash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &cpuat91_flash_data, - }, - .resource = &cpuat91_flash_resource, - .num_resources = 1, -}; - -#ifdef CONFIG_MTD_PLATRAM -struct platdata_mtd_ram at91_sram_pdata = { - .mapname = "SRAM", - .bankwidth = 2, -}; - -static struct resource at91_sram_resource[] = { - [0] = { - .start = AT91RM9200_SRAM_BASE, - .end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device at91_sram = { - .name = "mtd-ram", - .id = 0, - .resource = at91_sram_resource, - .num_resources = ARRAY_SIZE(at91_sram_resource), - .dev = { - .platform_data = &at91_sram_pdata, - }, -}; -#endif /* MTD_PLATRAM */ - -static struct platform_device *platform_devices[] __initdata = { - &cpuat91_norflash, -#ifdef CONFIG_MTD_PLATRAM - &at91_sram, -#endif /* CONFIG_MTD_PLATRAM */ -}; - -static void __init cpuat91_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | - ATMEL_UART_RTS); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | - ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART2 on ttyS3 (Rx, Tx) */ - at91_register_uart(AT91RM9200_ID_US2, 3, 0); - - /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS | - ATMEL_UART_RTS); - at91_add_device_serial(); - /* LEDs. */ - at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds)); - /* Ethernet */ - at91_add_device_eth(&cpuat91_eth_data); - /* USB Host */ - at91_add_device_usbh(&cpuat91_usbh_data); - /* USB Device */ - at91_add_device_udc(&cpuat91_udc_data); - /* MMC */ - at91_add_device_mci(0, &cpuat91_mci0_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* Platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); -} - -MACHINE_START(CPUAT91, "Eukrea") - /* Maintainer: Eric Benard - EUKREA Electromatique */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = cpuat91_init_early, - .init_irq = at91_init_irq_default, - .init_machine = cpuat91_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-csb337.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-csb337.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-csb337.c - * - * Copyright (C) 2005 SAN People - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/mtd/physmap.h> -#include <linux/input.h> -#include <linux/gpio_keys.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - -static void __init csb337_init_early(void) -{ - /* Initialize processor: 3.6864 MHz crystal */ - at91_initialize(3686400); -} - -static struct macb_platform_data __initdata csb337_eth_data = { - .phy_irq_pin = AT91_PIN_PC2, - .is_rmii = 0, - /* The CSB337 bootloader stores the MAC the wrong-way around */ - .rev_eth_addr = 1, -}; - -static struct at91_usbh_data __initdata csb337_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata csb337_udc_data = { - .pullup_pin = AT91_PIN_PA24, - .vbus_pin = -EINVAL, -}; - -static struct i2c_board_info __initdata csb337_i2c_devices[] = { - { - I2C_BOARD_INFO("ds1307", 0x68), - }, -}; - -static struct at91_cf_data __initdata csb337_cf_data = { - /* - * connector P4 on the CSB 337 mates to - * connector P8 on the CSB 300CF - */ - - /* CSB337 specific */ - .det_pin = AT91_PIN_PC3, - - /* CSB300CF specific */ - .irq_pin = AT91_PIN_PA19, - .vcc_pin = AT91_PIN_PD0, - .rst_pin = AT91_PIN_PD2, -}; - -static struct mci_platform_data __initdata csb337_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PD5, - .wp_pin = AT91_PIN_PD6, - }, -}; - -static struct spi_board_info csb337_spi_devices[] = { - { /* CAN controller */ - .modalias = "sak82c900", - .chip_select = 0, - .max_speed_hz = 6 * 1000 * 1000, - }, -}; - -#define CSB_FLASH_BASE AT91_CHIPSELECT_0 -#define CSB_FLASH_SIZE SZ_8M - -static struct mtd_partition csb_flash_partitions[] = { - { - .name = "uMON flash", - .offset = 0, - .size = MTDPART_SIZ_FULL, - .mask_flags = MTD_WRITEABLE, /* read only */ - } -}; - -static struct physmap_flash_data csb_flash_data = { - .width = 2, - .parts = csb_flash_partitions, - .nr_parts = ARRAY_SIZE(csb_flash_partitions), -}; - -static struct resource csb_flash_resources[] = { - { - .start = CSB_FLASH_BASE, - .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device csb_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &csb_flash_data, - }, - .resource = csb_flash_resources, - .num_resources = ARRAY_SIZE(csb_flash_resources), -}; - -/* - * GPIO Buttons (on CSB300) - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button csb300_buttons[] = { - { - .gpio = AT91_PIN_PB29, - .code = BTN_0, - .desc = "sw0", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB28, - .code = BTN_1, - .desc = "sw1", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA21, - .code = BTN_2, - .desc = "sw2", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data csb300_button_data = { - .buttons = csb300_buttons, - .nbuttons = ARRAY_SIZE(csb300_buttons), -}; - -static struct platform_device csb300_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &csb300_button_data, - } -}; - -static void __init csb300_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PB29, 1); /* sw0 */ - at91_set_deglitch(AT91_PIN_PB29, 1); - at91_set_gpio_input(AT91_PIN_PB28, 1); /* sw1 */ - at91_set_deglitch(AT91_PIN_PB28, 1); - at91_set_gpio_input(AT91_PIN_PA21, 1); /* sw2 */ - at91_set_deglitch(AT91_PIN_PA21, 1); - - platform_device_register(&csb300_button_device); -} -#else -static void __init csb300_add_device_buttons(void) {} -#endif - -static struct gpio_led csb_leds[] = { - { /* "led0", yellow */ - .name = "led0", - .gpio = AT91_PIN_PB2, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* "led1", green */ - .name = "led1", - .gpio = AT91_PIN_PB1, - .active_low = 1, - .default_trigger = "mmc0", - }, - { /* "led2", yellow */ - .name = "led2", - .gpio = AT91_PIN_PB0, - .active_low = 1, - .default_trigger = "ide-disk", - } -}; - - -static void __init csb337_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0 */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&csb337_eth_data); - /* USB Host */ - at91_add_device_usbh(&csb337_usbh_data); - /* USB Device */ - at91_add_device_udc(&csb337_udc_data); - /* I2C */ - at91_add_device_i2c(csb337_i2c_devices, ARRAY_SIZE(csb337_i2c_devices)); - /* Compact Flash */ - at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */ - at91_add_device_cf(&csb337_cf_data); - /* SPI */ - at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices)); - /* MMC */ - at91_add_device_mci(0, &csb337_mci0_data); - /* NOR flash */ - platform_device_register(&csb_flash); - /* LEDs */ - at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); - /* Switches on CSB300 */ - csb300_add_device_buttons(); -} - -MACHINE_START(CSB337, "Cogent CSB337") - /* Maintainer: Bill Gatliff */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = csb337_init_early, - .init_irq = at91_init_irq_default, - .init_machine = csb337_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-csb637.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-csb637.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-csb637.c - * - * Copyright (C) 2005 SAN People - * - * 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 - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init csb637_init_early(void) -{ - /* Initialize processor: 3.6864 MHz crystal */ - at91_initialize(3686400); -} - -static struct macb_platform_data __initdata csb637_eth_data = { - .phy_irq_pin = AT91_PIN_PC0, - .is_rmii = 0, -}; - -static struct at91_usbh_data __initdata csb637_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata csb637_udc_data = { - .vbus_pin = AT91_PIN_PB28, - .pullup_pin = AT91_PIN_PB1, -}; - -#define CSB_FLASH_BASE AT91_CHIPSELECT_0 -#define CSB_FLASH_SIZE SZ_16M - -static struct mtd_partition csb_flash_partitions[] = { - { - .name = "uMON flash", - .offset = 0, - .size = MTDPART_SIZ_FULL, - .mask_flags = MTD_WRITEABLE, /* read only */ - } -}; - -static struct physmap_flash_data csb_flash_data = { - .width = 2, - .parts = csb_flash_partitions, - .nr_parts = ARRAY_SIZE(csb_flash_partitions), -}; - -static struct resource csb_flash_resources[] = { - { - .start = CSB_FLASH_BASE, - .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device csb_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &csb_flash_data, - }, - .resource = csb_flash_resources, - .num_resources = ARRAY_SIZE(csb_flash_resources), -}; - -static struct gpio_led csb_leds[] = { - { /* "d1", red */ - .name = "d1", - .gpio = AT91_PIN_PB2, - .active_low = 1, - .default_trigger = "heartbeat", - }, -}; - -static void __init csb637_board_init(void) -{ - /* LED(s) */ - at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&csb637_eth_data); - /* USB Host */ - at91_add_device_usbh(&csb637_usbh_data); - /* USB Device */ - at91_add_device_udc(&csb637_udc_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* SPI */ - at91_add_device_spi(NULL, 0); - /* NOR flash */ - platform_device_register(&csb_flash); -} - -MACHINE_START(CSB637, "Cogent CSB637") - /* Maintainer: Bill Gatliff */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = csb637_init_early, - .init_irq = at91_init_irq_default, - .init_machine = csb637_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-rm9200.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-dt-rm9200.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-rm9200.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:17 @ #include <linux/gpio.h> #include <linux/of.h> #include <linux/of_irq.h> +#include <linux/of_platform.h> #include <linux/clk-provider.h> #include <asm/setup.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:26 @ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include "at91_aic.h" #include "generic.h" static void __init at91rm9200_dt_timer_init(void) { -#if defined(CONFIG_COMMON_CLK) of_clk_init(NULL); -#endif at91rm9200_timer_init(); } -static const char *at91rm9200_dt_board_compat[] __initdata = { +static void __init at91rm9200_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + + at91rm9200_pm_init(); +} + + + +static const char *at91rm9200_dt_board_compat[] __initconst = { "atmel,at91rm9200", NULL }; -DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") +DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200") .init_time = at91rm9200_dt_timer_init, .map_io = at91_map_io, .init_early = at91rm9200_dt_initialize, + .init_machine = at91rm9200_dt_device_init, .dt_compat = at91rm9200_dt_board_compat, MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-sam9.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-dt-sam9.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-sam9.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:16 @ #include <linux/gpio.h> #include <linux/of.h> #include <linux/of_irq.h> +#include <linux/of_platform.h> #include <linux/clk-provider.h> #include <asm/setup.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include "at91_aic.h" -#include "board.h" #include "generic.h" -static const char *at91_dt_board_compat[] __initdata = { +static void __init at91sam9_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + at91sam9260_pm_init(); +} + +static const char *at91_dt_board_compat[] __initconst = { "atmel,at91sam9", NULL }; -DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") +DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9") /* Maintainer: Atmel */ .map_io = at91_map_io, .init_early = at91_dt_initialize, + .init_machine = at91sam9_dt_device_init, .dt_compat = at91_dt_board_compat, MACHINE_END + +static void __init at91sam9g45_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + at91sam9g45_pm_init(); +} + +static const char *at91sam9g45_board_compat[] __initconst = { + "atmel,at91sam9g45", + NULL +}; + +DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45") + /* Maintainer: Atmel */ + .map_io = at91_map_io, + .init_early = at91_dt_initialize, + .init_machine = at91sam9g45_dt_device_init, + .dt_compat = at91sam9g45_board_compat, +MACHINE_END + +static void __init at91sam9x5_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + at91sam9x5_pm_init(); +} + +static const char *at91sam9x5_board_compat[] __initconst = { + "atmel,at91sam9x5", + "atmel,at91sam9n12", + NULL +}; + +DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9") + /* Maintainer: Atmel */ + .map_io = at91_map_io, + .init_early = at91_dt_initialize, + .init_machine = at91sam9x5_dt_device_init, + .dt_compat = at91sam9x5_board_compat, +MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-sama5.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-dt-sama5.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-dt-sama5.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:20 @ #include <linux/of_platform.h> #include <linux/phy.h> #include <linux/clk-provider.h> +#include <linux/phy.h> #include <asm/setup.h> #include <asm/irq.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:28 @ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include "at91_aic.h" #include "generic.h" +static int ksz8081_phy_fixup(struct phy_device *phy) +{ + int value; + + value = phy_read(phy, 0x16); + value &= ~0x20; + phy_write(phy, 0x16, value); + + return 0; +} + static void __init sama5_dt_device_init(void) { + if (of_machine_is_compatible("atmel,sama5d4ek") && + IS_ENABLED(CONFIG_PHYLIB)) { + phy_register_fixup_for_id("fc028000.etherne:00", + ksz8081_phy_fixup); + } + + if (of_machine_is_compatible("atmel,sama5d3xmb") && + IS_ENABLED(CONFIG_PHYLIB)) { + phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK, + ksz8081_phy_fixup); + } + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + sam5d3_pm_init(); } static const char *sama5_dt_board_compat[] __initconst = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:64 @ static const char *sama5_dt_board_compat NULL }; -DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") +DT_MACHINE_START(sama5_dt, "Atmel SAMA5") /* Maintainer: Atmel */ .map_io = at91_map_io, .init_early = at91_dt_initialize, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:72 @ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 .dt_compat = sama5_dt_board_compat, MACHINE_END +static void __init sama5d4_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + sam5d4_pm_init(); +} + static const char *sama5_alt_dt_board_compat[] __initconst = { "atmel,sama5d4", NULL }; -DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5 (Device Tree)") +DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") /* Maintainer: Atmel */ .map_io = at91_alt_map_io, .init_early = at91_dt_initialize, - .init_machine = sama5_dt_device_init, + .init_machine = sama5d4_dt_device_init, .dt_compat = sama5_alt_dt_board_compat, .l2c_aux_mask = ~0UL, MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-eb01.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-eb01.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/board-eb01.c - * - * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> - * - * 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 - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/irq.h> -#include <asm/mach-types.h> -#include <mach/hardware.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" - -static void __init at91eb01_init_irq(void) -{ - at91x40_init_interrupts(NULL); -} - -static void __init at91eb01_init_early(void) -{ - at91x40_initialize(40000000); -} - -MACHINE_START(AT91EB01, "Atmel AT91 EB01") - /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ - .init_time = at91x40_timer_init, - .handle_irq = at91_aic_handle_irq, - .init_early = at91eb01_init_early, - .init_irq = at91eb01_init_irq, -MACHINE_END - Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-eb9200.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-eb9200.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-eb9200.c - * - * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest - * by Andrew Patrikalakis - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/device.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init eb9200_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata eb9200_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata eb9200_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata eb9200_udc_data = { - .vbus_pin = AT91_PIN_PD4, - .pullup_pin = AT91_PIN_PD5, -}; - -static struct at91_cf_data __initdata eb9200_cf_data = { - .irq_pin = -EINVAL, - .det_pin = AT91_PIN_PB0, - .vcc_pin = -EINVAL, - .rst_pin = AT91_PIN_PC5, -}; - -static struct mci_platform_data __initdata eb9200_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - -static struct i2c_board_info __initdata eb9200_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50), - }, -}; - - -static void __init eb9200_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART2 on ttyS2. (Rx, Tx) - IRDA */ - at91_register_uart(AT91RM9200_ID_US2, 2, 0); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&eb9200_eth_data); - /* USB Host */ - at91_add_device_usbh(&eb9200_usbh_data); - /* USB Device */ - at91_add_device_udc(&eb9200_udc_data); - /* I2C */ - at91_add_device_i2c(eb9200_i2c_devices, ARRAY_SIZE(eb9200_i2c_devices)); - /* Compact Flash */ - at91_add_device_cf(&eb9200_cf_data); - /* SPI */ - at91_add_device_spi(NULL, 0); - /* MMC */ - /* only supports 1 or 4 bit interface, not wired through to SPI */ - at91_add_device_mci(0, &eb9200_mci0_data); -} - -MACHINE_START(ATEB9200, "Embest ATEB9200") - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = eb9200_init_early, - .init_irq = at91_init_irq_default, - .init_machine = eb9200_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-ecbat91.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-ecbat91.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91rm9200/board-ecbat91.c - * Copyright (C) 2007 emQbit.com. - * - * We started from board-dk.c, which is Copyright (C) 2005 SAN People. - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/flash.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ecb_at91init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata ecb_at91eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 0, -}; - -static struct at91_usbh_data __initdata ecb_at91usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct mci_platform_data __initdata ecbat91_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - - -#if defined(CONFIG_MTD_DATAFLASH) -static struct mtd_partition __initdata my_flash0_partitions[] = -{ - { /* 0x8400 */ - .name = "Darrell-loader", - .offset = 0, - .size = 12 * 1056, - }, - { - .name = "U-boot", - .offset = MTDPART_OFS_NXTBLK, - .size = 110 * 1056, - }, - { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */ - .name = "UBoot-env", - .offset = MTDPART_OFS_NXTBLK, - .size = 8 * 1056, - }, - { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */ - .name = "Kernel", - .offset = MTDPART_OFS_NXTBLK, - .size = 1534 * 1056, - }, - { /* 190200 - jffs2 root filesystem */ - .name = "Filesystem", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, /* 26 sectors */ - } -}; - -static struct flash_platform_data __initdata my_flash0_platform = { - .name = "Removable flash card", - .parts = my_flash0_partitions, - .nr_parts = ARRAY_SIZE(my_flash0_partitions) -}; - -#endif - -static struct spi_board_info __initdata ecb_at91spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 10 * 1000 * 1000, - .bus_num = 0, -#if defined(CONFIG_MTD_DATAFLASH) - .platform_data = &my_flash0_platform, -#endif - }, - { /* User accessible spi - cs1 (250KHz) */ - .modalias = "spi-cs1", - .chip_select = 1, - .max_speed_hz = 250 * 1000, - }, - { /* User accessible spi - cs2 (1MHz) */ - .modalias = "spi-cs2", - .chip_select = 2, - .max_speed_hz = 1 * 1000 * 1000, - }, - { /* User accessible spi - cs3 (10MHz) */ - .modalias = "spi-cs3", - .chip_select = 3, - .max_speed_hz = 10 * 1000 * 1000, - }, -}; - -/* - * LEDs - */ -static struct gpio_led ecb_leds[] = { - { /* D1 */ - .name = "led1", - .gpio = AT91_PIN_PC7, - .active_low = 1, - .default_trigger = "heartbeat", - } -}; - -static void __init ecb_at91board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx & Tx only) */ - at91_register_uart(AT91RM9200_ID_US0, 1, 0); - at91_add_device_serial(); - - /* Ethernet */ - at91_add_device_eth(&ecb_at91eth_data); - - /* USB Host */ - at91_add_device_usbh(&ecb_at91usbh_data); - - /* I2C */ - at91_add_device_i2c(NULL, 0); - - /* MMC */ - at91_add_device_mci(0, &ecbat91_mci0_data); - - /* SPI */ - at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices)); - - /* LEDs */ - at91_gpio_leds(ecb_leds, ARRAY_SIZE(ecb_leds)); -} - -MACHINE_START(ECBAT91, "emQbit's ECB_AT91") - /* Maintainer: emQbit.com */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ecb_at91init_early, - .init_irq = at91_init_irq_default, - .init_machine = ecb_at91board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-eco920.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-eco920.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/gpio.h> - -#include <asm/mach-types.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init eco920_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata eco920_eth_data = { - .phy_irq_pin = AT91_PIN_PC2, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata eco920_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata eco920_udc_data = { - .vbus_pin = AT91_PIN_PB12, - .pullup_pin = AT91_PIN_PB13, -}; - -static struct mci_platform_data __initdata eco920_mci0_data = { - .slot[0] = { - .bus_width = 1, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - -static struct physmap_flash_data eco920_flash_data = { - .width = 2, -}; - -static struct resource eco920_flash_resource = { - .start = 0x11000000, - .end = 0x11ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device eco920_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &eco920_flash_data, - }, - .resource = &eco920_flash_resource, - .num_resources = 1, -}; - -static struct spi_board_info eco920_spi_devices[] = { - { /* CAN controller */ - .modalias = "tlv5638", - .chip_select = 3, - .max_speed_hz = 20 * 1000 * 1000, - .mode = SPI_CPHA, - }, -}; - -/* - * LEDs - */ -static struct gpio_led eco920_leds[] = { - { /* D1 */ - .name = "led1", - .gpio = AT91_PIN_PB0, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* D2 */ - .name = "led2", - .gpio = AT91_PIN_PB1, - .active_low = 1, - .default_trigger = "timer", - } -}; - -static void __init eco920_board_init(void) -{ - /* DBGU on ttyS0. (Rx & Tx only */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - at91_add_device_eth(&eco920_eth_data); - at91_add_device_usbh(&eco920_usbh_data); - at91_add_device_udc(&eco920_udc_data); - - at91_add_device_mci(0, &eco920_mci0_data); - platform_device_register(&eco920_flash); - - at91_ramc_write(0, AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) - | AT91_SMC_RWSETUP_(1) - | AT91_SMC_DBW_8 - | AT91_SMC_WSEN - | AT91_SMC_NWS_(15)); - - at91_set_A_periph(AT91_PIN_PC6, 1); - - at91_set_gpio_input(AT91_PIN_PA23, 0); - at91_set_deglitch(AT91_PIN_PA23, 1); - -/* Initialization of the Static Memory Controller for Chip Select 3 */ - at91_ramc_write(0, AT91_SMC_CSR(3), - AT91_SMC_DBW_16 | /* 16 bit */ - AT91_SMC_WSEN | - AT91_SMC_NWS_(5) | /* wait states */ - AT91_SMC_TDF_(1) /* float time */ - ); - - at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices)); - /* LEDs */ - at91_gpio_leds(eco920_leds, ARRAY_SIZE(eco920_leds)); -} - -MACHINE_START(ECO920, "eco920") - /* Maintainer: Sascha Hauer */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = eco920_init_early, - .init_irq = at91_init_irq_default, - .init_machine = eco920_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-flexibity.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-flexibity.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-flexibity.c - * - * Copyright (C) 2010-2011 Flexibity - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * - * 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 - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/input.h> -#include <linux/gpio.h> - -#include <asm/mach-types.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - -static void __init flexibity_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* USB Host port */ -static struct at91_usbh_data __initdata flexibity_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* USB Device port */ -static struct at91_udc_data __initdata flexibity_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - -/* I2C devices */ -static struct i2c_board_info __initdata flexibity_i2c_devices[] = { - { - I2C_BOARD_INFO("ds1307", 0x68), - }, -}; - -/* SPI devices */ -static struct spi_board_info flexibity_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -}; - -/* MCI (SD/MMC) */ -static struct mci_platform_data __initdata flexibity_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC9, - .wp_pin = AT91_PIN_PC4, - }, -}; - -/* LEDs */ -static struct gpio_led flexibity_leds[] = { - { - .name = "usb1:green", - .gpio = AT91_PIN_PA12, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb1:red", - .gpio = AT91_PIN_PA13, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb2:green", - .gpio = AT91_PIN_PB26, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb2:red", - .gpio = AT91_PIN_PB27, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb3:green", - .gpio = AT91_PIN_PC8, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb3:red", - .gpio = AT91_PIN_PC6, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb4:green", - .gpio = AT91_PIN_PB4, - .active_low = 1, - .default_trigger = "default-on", - }, - { - .name = "usb4:red", - .gpio = AT91_PIN_PB5, - .active_low = 1, - .default_trigger = "default-on", - } -}; - -static void __init flexibity_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&flexibity_usbh_data); - /* USB Device */ - at91_add_device_udc(&flexibity_udc_data); - /* I2C */ - at91_add_device_i2c(flexibity_i2c_devices, - ARRAY_SIZE(flexibity_i2c_devices)); - /* SPI */ - at91_add_device_spi(flexibity_spi_devices, - ARRAY_SIZE(flexibity_spi_devices)); - /* MMC */ - at91_add_device_mci(0, &flexibity_mci0_data); - /* LEDs */ - at91_gpio_leds(flexibity_leds, ARRAY_SIZE(flexibity_leds)); -} - -MACHINE_START(FLEXIBITY, "Flexibity Connect") - /* Maintainer: Maxim Osipov */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = flexibity_init_early, - .init_irq = at91_init_irq_default, - .init_machine = flexibity_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-gsia18s.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-gsia18s.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> - * taskit GmbH - * 2010 Igor Plyatov <plyatov@gmail.com> - * GeoSIG 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. - * - * 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 <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/w1-gpio.h> -#include <linux/i2c.h> -#include <linux/i2c/pcf857x.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gsia18s.h" -#include "stamp9g20.h" -#include "gpio.h" - -static void __init gsia18s_init_early(void) -{ - stamp9g20_init_early(); -} - -/* - * Two USB Host ports - */ -static struct at91_usbh_data __initdata usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata udc_data = { - .vbus_pin = AT91_PIN_PA22, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata macb_data = { - .phy_irq_pin = AT91_PIN_PA28, - .is_rmii = 1, -}; - -/* - * LEDs and GPOs - */ -static struct gpio_led gpio_leds[] = { - { - .name = "gpo:spi1reset", - .gpio = AT91_PIN_PC1, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "gpo:trig_net_out", - .gpio = AT91_PIN_PB20, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "gpo:trig_net_dir", - .gpio = AT91_PIN_PB19, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "gpo:charge_dis", - .gpio = AT91_PIN_PC2, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "led:event", - .gpio = AT91_PIN_PB17, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "led:lan", - .gpio = AT91_PIN_PB18, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "led:error", - .gpio = AT91_PIN_PB16, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_ON, - } -}; - -static struct gpio_led_platform_data gpio_led_info = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), -}; - -static struct platform_device leds = { - .name = "leds-gpio", - .id = 0, - .dev = { - .platform_data = &gpio_led_info, - } -}; - -static void __init gsia18s_leds_init(void) -{ - platform_device_register(&leds); -} - -/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */ -static struct gpio_led pcf_gpio_leds1[] = { - { /* bit 0 */ - .name = "gpo:hdc_power", - .gpio = PCF_GPIO_HDC_POWER, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 1 */ - .name = "gpo:wifi_setup", - .gpio = PCF_GPIO_WIFI_SETUP, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 2 */ - .name = "gpo:wifi_enable", - .gpio = PCF_GPIO_WIFI_ENABLE, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 3 */ - .name = "gpo:wifi_reset", - .gpio = PCF_GPIO_WIFI_RESET, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_ON, - }, - /* bit 4 used as GPI */ - { /* bit 5 */ - .name = "gpo:gps_setup", - .gpio = PCF_GPIO_GPS_SETUP, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 6 */ - .name = "gpo:gps_standby", - .gpio = PCF_GPIO_GPS_STANDBY, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_ON, - }, - { /* bit 7 */ - .name = "gpo:gps_power", - .gpio = PCF_GPIO_GPS_POWER, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - } -}; - -static struct gpio_led_platform_data pcf_gpio_led_info1 = { - .leds = pcf_gpio_leds1, - .num_leds = ARRAY_SIZE(pcf_gpio_leds1), -}; - -static struct platform_device pcf_leds1 = { - .name = "leds-gpio", /* GS_IA18-CB_board */ - .id = 1, - .dev = { - .platform_data = &pcf_gpio_led_info1, - } -}; - -/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ -static struct gpio_led pcf_gpio_leds2[] = { - { /* bit 0 */ - .name = "gpo:alarm_1", - .gpio = PCF_GPIO_ALARM1, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 1 */ - .name = "gpo:alarm_2", - .gpio = PCF_GPIO_ALARM2, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 2 */ - .name = "gpo:alarm_3", - .gpio = PCF_GPIO_ALARM3, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { /* bit 3 */ - .name = "gpo:alarm_4", - .gpio = PCF_GPIO_ALARM4, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - /* bits 4, 5, 6 not used */ - { /* bit 7 */ - .name = "gpo:alarm_v_relay_on", - .gpio = PCF_GPIO_ALARM_V_RELAY_ON, - .active_low = 0, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, -}; - -static struct gpio_led_platform_data pcf_gpio_led_info2 = { - .leds = pcf_gpio_leds2, - .num_leds = ARRAY_SIZE(pcf_gpio_leds2), -}; - -static struct platform_device pcf_leds2 = { - .name = "leds-gpio", - .id = 2, - .dev = { - .platform_data = &pcf_gpio_led_info2, - } -}; - -/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */ -static struct gpio_led pcf_gpio_leds3[] = { - { /* bit 0 */ - .name = "gpo:modem_power", - .gpio = PCF_GPIO_MODEM_POWER, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - /* bits 1 and 2 not used */ - { /* bit 3 */ - .name = "gpo:modem_reset", - .gpio = PCF_GPIO_MODEM_RESET, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_ON, - }, - /* bits 4, 5 and 6 not used */ - { /* bit 7 */ - .name = "gpo:trx_reset", - .gpio = PCF_GPIO_TRX_RESET, - .active_low = 1, - .default_trigger = "none", - .default_state = LEDS_GPIO_DEFSTATE_ON, - } -}; - -static struct gpio_led_platform_data pcf_gpio_led_info3 = { - .leds = pcf_gpio_leds3, - .num_leds = ARRAY_SIZE(pcf_gpio_leds3), -}; - -static struct platform_device pcf_leds3 = { - .name = "leds-gpio", - .id = 3, - .dev = { - .platform_data = &pcf_gpio_led_info3, - } -}; - -static void __init gsia18s_pcf_leds_init(void) -{ - platform_device_register(&pcf_leds1); - platform_device_register(&pcf_leds2); - platform_device_register(&pcf_leds3); -} - -/* - * SPI busses. - */ -static struct spi_board_info gsia18s_spi_devices[] = { - { /* User accessible spi0, cs0 used for communication with MSP RTC */ - .modalias = "spidev", - .bus_num = 0, - .chip_select = 0, - .max_speed_hz = 580000, - .mode = SPI_MODE_1, - }, - { /* User accessible spi1, cs0 used for communication with int. DSP */ - .modalias = "spidev", - .bus_num = 1, - .chip_select = 0, - .max_speed_hz = 5600000, - .mode = SPI_MODE_0, - }, - { /* User accessible spi1, cs1 used for communication with ext. DSP */ - .modalias = "spidev", - .bus_num = 1, - .chip_select = 1, - .max_speed_hz = 5600000, - .mode = SPI_MODE_0, - }, - { /* User accessible spi1, cs2 used for communication with ext. DSP */ - .modalias = "spidev", - .bus_num = 1, - .chip_select = 2, - .max_speed_hz = 5600000, - .mode = SPI_MODE_0, - }, - { /* User accessible spi1, cs3 used for communication with ext. DSP */ - .modalias = "spidev", - .bus_num = 1, - .chip_select = 3, - .max_speed_hz = 5600000, - .mode = SPI_MODE_0, - } -}; - -/* - * GPI Buttons - */ -static struct gpio_keys_button buttons[] = { - { - .gpio = GPIO_TRIG_NET_IN, - .code = BTN_1, - .desc = "TRIG_NET_IN", - .type = EV_KEY, - .active_low = 0, - .wakeup = 1, - }, - { /* SW80 on the GS_IA18_S-MN board*/ - .gpio = GPIO_CARD_UNMOUNT_0, - .code = BTN_2, - .desc = "Card umount 0", - .type = EV_KEY, - .active_low = 1, - .wakeup = 1, - }, - { /* SW79 on the GS_IA18_S-MN board*/ - .gpio = GPIO_CARD_UNMOUNT_1, - .code = BTN_3, - .desc = "Card umount 1", - .type = EV_KEY, - .active_low = 1, - .wakeup = 1, - }, - { /* SW280 on the GS_IA18-CB board*/ - .gpio = GPIO_KEY_POWER, - .code = KEY_POWER, - .desc = "Power Off Button", - .type = EV_KEY, - .active_low = 0, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data button_data = { - .buttons = buttons, - .nbuttons = ARRAY_SIZE(buttons), -}; - -static struct platform_device button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &button_data, - } -}; - -static void __init gsia18s_add_device_buttons(void) -{ - at91_set_gpio_input(GPIO_TRIG_NET_IN, 1); - at91_set_deglitch(GPIO_TRIG_NET_IN, 1); - at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1); - at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1); - at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1); - at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1); - at91_set_gpio_input(GPIO_KEY_POWER, 0); - at91_set_deglitch(GPIO_KEY_POWER, 1); - - platform_device_register(&button_device); -} - -/* - * I2C - */ -static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio, - unsigned int ngpio, void *context) -{ - int status; - - status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det"); - if (status < 0) { - pr_err("error: can't request GPIO%d\n", - gpio + PCF_GPIO_ETH_DETECT); - return status; - } - status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT); - if (status < 0) { - pr_err("error: can't setup GPIO%d as input\n", - gpio + PCF_GPIO_ETH_DETECT); - return status; - } - status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false); - if (status < 0) { - pr_err("error: can't export GPIO%d\n", - gpio + PCF_GPIO_ETH_DETECT); - return status; - } - status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1); - if (status < 0) { - pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n", - gpio + PCF_GPIO_ETH_DETECT); - return status; - } - - return 0; -} - -static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio, - unsigned ngpio, void *context) -{ - gpio_free(gpio + PCF_GPIO_ETH_DETECT); - return 0; -} - -static struct pcf857x_platform_data pcf20_pdata = { - .gpio_base = GS_IA18_S_PCF_GPIO_BASE0, - .n_latch = (1 << 4), - .setup = pcf8574x_0x20_setup, - .teardown = pcf8574x_0x20_teardown, -}; - -static struct pcf857x_platform_data pcf22_pdata = { - .gpio_base = GS_IA18_S_PCF_GPIO_BASE1, -}; - -static struct pcf857x_platform_data pcf24_pdata = { - .gpio_base = GS_IA18_S_PCF_GPIO_BASE2, -}; - -static struct i2c_board_info __initdata gsia18s_i2c_devices[] = { - { /* U1 on the GS_IA18-CB_V3 board */ - I2C_BOARD_INFO("pcf8574", 0x20), - .platform_data = &pcf20_pdata, - }, - { /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ - I2C_BOARD_INFO("pcf8574", 0x22), - .platform_data = &pcf22_pdata, - }, - { /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */ - I2C_BOARD_INFO("pcf8574", 0x24), - .platform_data = &pcf24_pdata, - }, - { /* U161 on the GS_IA18_S-MN board */ - I2C_BOARD_INFO("24c1024", 0x50), - }, - { /* U162 on the GS_IA18_S-MN board */ - I2C_BOARD_INFO("24c01", 0x53), - }, -}; - -/* - * Compact Flash - */ -static struct at91_cf_data __initdata gsia18s_cf1_data = { - .irq_pin = AT91_PIN_PA27, - .det_pin = AT91_PIN_PB30, - .vcc_pin = -EINVAL, - .rst_pin = AT91_PIN_PB31, - .chipselect = 5, - .flags = AT91_CF_TRUE_IDE, -}; - -/* Power Off by RTC */ -static void gsia18s_power_off(void) -{ - pr_notice("Power supply will be switched off automatically now or after 60 seconds without ArmDAS.\n"); - at91_set_gpio_output(AT91_PIN_PA25, 1); - /* Spin to death... */ - while (1) - ; -} - -static int __init gsia18s_power_off_init(void) -{ - pm_power_off = gsia18s_power_off; - return 0; -} - -/* ---------------------------------------------------------------------------*/ - -static void __init gsia18s_board_init(void) -{ - /* - * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). - * Used for Internal Analog Modem. - */ - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS | - ATMEL_UART_DTR | ATMEL_UART_DSR | - ATMEL_UART_DCD | ATMEL_UART_RI); - /* - * USART1 on ttyS2 (Rx, Tx, CTS, RTS). - * Used for GPS or WiFi or Data stream. - */ - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); - /* - * USART2 on ttyS3 (Rx, Tx, CTS, RTS). - * Used for External Modem. - */ - at91_register_uart(AT91SAM9260_ID_US2, 3, - ATMEL_UART_CTS | ATMEL_UART_RTS); - /* - * USART3 on ttyS4 (Rx, Tx, RTS). - * Used for RS-485. - */ - at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS); - - /* - * USART4 on ttyS5 (Rx, Tx). - * Used for TRX433 Radio Module. - */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - stamp9g20_board_init(); - at91_add_device_usbh(&usbh_data); - at91_add_device_udc(&udc_data); - at91_add_device_eth(&macb_data); - gsia18s_leds_init(); - gsia18s_pcf_leds_init(); - gsia18s_add_device_buttons(); - at91_add_device_i2c(gsia18s_i2c_devices, - ARRAY_SIZE(gsia18s_i2c_devices)); - at91_add_device_cf(&gsia18s_cf1_data); - at91_add_device_spi(gsia18s_spi_devices, - ARRAY_SIZE(gsia18s_spi_devices)); - gsia18s_power_off_init(); -} - -MACHINE_START(GSIA18S, "GS_IA18_S") - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = gsia18s_init_early, - .init_irq = at91_init_irq_default, - .init_machine = gsia18s_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/board.h - * - * Copyright (C) 2005 HP Labs - * - * 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 - */ - -/* - * These are data structures found in platform_device.dev.platform_data, - * and describing board-specific data needed by drivers. For example, - * which pin is used for a given GPIO role. - * - * In 2.6, drivers should strongly avoid board-specific knowledge so - * that supporting new boards normally won't require driver patches. - * Most board-specific knowledge should be in arch/.../board-*.c files. - */ - -#ifndef __ASM_ARCH_BOARD_H -#define __ASM_ARCH_BOARD_H - -#include <linux/platform_data/atmel.h> - - /* USB Device */ -extern void __init at91_add_device_udc(struct at91_udc_data *data); - - /* USB High Speed Device */ -extern void __init at91_add_device_usba(struct usba_platform_data *data); - - /* Compact Flash */ -extern void __init at91_add_device_cf(struct at91_cf_data *data); - - /* MMC / SD */ - /* atmel-mci platform config */ -extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); - -extern void __init at91_add_device_eth(struct macb_platform_data *data); - - /* USB Host */ -extern void __init at91_add_device_usbh(struct at91_usbh_data *data); -extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); -extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); - -extern void __init at91_add_device_nand(struct atmel_nand_data *data); - - /* I2C*/ -#if defined(CONFIG_ARCH_AT91SAM9G45) -extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices); -#else -extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); -#endif - - /* SPI */ -extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); - - /* Serial */ -#define ATMEL_UART_CTS 0x01 -#define ATMEL_UART_RTS 0x02 -#define ATMEL_UART_DSR 0x04 -#define ATMEL_UART_DTR 0x08 -#define ATMEL_UART_DCD 0x10 -#define ATMEL_UART_RI 0x20 - -extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins); - -extern struct platform_device *atmel_default_console_device; - -extern void __init at91_add_device_serial(void); - -/* - * PWM - */ -#define AT91_PWM0 0 -#define AT91_PWM1 1 -#define AT91_PWM2 2 -#define AT91_PWM3 3 - -extern void __init at91_add_device_pwm(u32 mask); - -/* - * SSC -- accessed through ssc_request(id). Drivers don't bind to SSC - * platform devices. Their SSC ID is part of their configuration data, - * along with information about which SSC signals they should use. - */ -#define ATMEL_SSC_TK 0x01 -#define ATMEL_SSC_TF 0x02 -#define ATMEL_SSC_TD 0x04 -#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD) - -#define ATMEL_SSC_RK 0x10 -#define ATMEL_SSC_RF 0x20 -#define ATMEL_SSC_RD 0x40 -#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD) - -extern void __init at91_add_device_ssc(unsigned id, unsigned pins); - - /* LCD Controller */ -struct atmel_lcdfb_pdata; -extern void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data); - - /* AC97 */ -extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); - - /* ISI */ -struct isi_platform_data; -extern void __init at91_add_device_isi(struct isi_platform_data *data, - bool use_pck_as_mck); - -/* CAN */ -extern void __init at91_add_device_can(struct at91_can_data *data); - - /* LEDs */ -extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-kafa.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-kafa.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-kafa.c - * - * Copyright (C) 2006 Sperry-Sun - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init kafa_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata kafa_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 0, -}; - -static struct at91_usbh_data __initdata kafa_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata kafa_udc_data = { - .vbus_pin = AT91_PIN_PB6, - .pullup_pin = AT91_PIN_PB7, -}; - -/* - * LEDs - */ -static struct gpio_led kafa_leds[] = { - { /* D1 */ - .name = "led1", - .gpio = AT91_PIN_PB4, - .active_low = 1, - .default_trigger = "heartbeat", - }, -}; - -static void __init kafa_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&kafa_eth_data); - /* USB Host */ - at91_add_device_usbh(&kafa_usbh_data); - /* USB Device */ - at91_add_device_udc(&kafa_udc_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* SPI */ - at91_add_device_spi(NULL, 0); - /* LEDs */ - at91_gpio_leds(kafa_leds, ARRAY_SIZE(kafa_leds)); -} - -MACHINE_START(KAFA, "Sperry-Sun KAFA") - /* Maintainer: Sergei Sharonov */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = kafa_init_early, - .init_irq = at91_init_irq_default, - .init_machine = kafa_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-kb9202.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-kb9202.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-kb9202.c - * - * Copyright (c) 2005 kb_admin - * KwikByte, Inc. - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/cpu.h> -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init kb9202_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 10 MHz crystal */ - at91_initialize(10000000); -} - -static struct macb_platform_data __initdata kb9202_eth_data = { - .phy_irq_pin = AT91_PIN_PB29, - .is_rmii = 0, -}; - -static struct at91_usbh_data __initdata kb9202_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata kb9202_udc_data = { - .vbus_pin = AT91_PIN_PB24, - .pullup_pin = AT91_PIN_PB22, -}; - -static struct mci_platform_data __initdata kb9202_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PB2, - .wp_pin = -EINVAL, - }, -}; - -static struct mtd_partition __initdata kb9202_nand_partition[] = { - { - .name = "nand_fs", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata kb9202_nand_data = { - .ale = 22, - .cle = 21, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC29, - .enable_pin = AT91_PIN_PC28, - .ecc_mode = NAND_ECC_SOFT, - .parts = kb9202_nand_partition, - .num_parts = ARRAY_SIZE(kb9202_nand_partition), -}; - -/* - * LEDs - */ -static struct gpio_led kb9202_leds[] = { - { /* D1 */ - .name = "led1", - .gpio = AT91_PIN_PC19, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* D2 */ - .name = "led2", - .gpio = AT91_PIN_PC18, - .active_low = 1, - .default_trigger = "timer", - } -}; - -static void __init kb9202_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1 (Rx & Tx only) */ - at91_register_uart(AT91RM9200_ID_US0, 1, 0); - - /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */ - at91_register_uart(AT91RM9200_ID_US1, 2, 0); - - /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */ - at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&kb9202_eth_data); - /* USB Host */ - at91_add_device_usbh(&kb9202_usbh_data); - /* USB Device */ - at91_add_device_udc(&kb9202_udc_data); - /* MMC */ - at91_add_device_mci(0, &kb9202_mci0_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* SPI */ - at91_add_device_spi(NULL, 0); - /* NAND */ - at91_add_device_nand(&kb9202_nand_data); - /* LEDs */ - at91_gpio_leds(kb9202_leds, ARRAY_SIZE(kb9202_leds)); -} - -MACHINE_START(KB9200, "KB920x") - /* Maintainer: KwikByte, Inc. */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = kb9202_init_early, - .init_irq = at91_init_irq_default, - .init_machine = kb9202_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-pcontrol-g20.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-pcontrol-g20.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> - * taskit GmbH - * - * 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 - */ -/* - * copied and adjusted from board-stamp9g20.c - * by Peter Gsellmann <pgsellmann@portner-elektronik.at> - */ - -#include <linux/mm.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/w1-gpio.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "stamp9g20.h" -#include "gpio.h" - - -static void __init pcontrol_g20_init_early(void) -{ - stamp9g20_init_early(); -} - -static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { - .ncs_read_setup = 16, - .nrd_setup = 18, - .ncs_write_setup = 16, - .nwe_setup = 18, - - .ncs_read_pulse = 63, - .nrd_pulse = 55, - .ncs_write_pulse = 63, - .nwe_pulse = 55, - - .read_cycle = 127, - .write_cycle = 127, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT - | AT91_SMC_DBW_8 | AT91_SMC_PS_4 - | AT91_SMC_TDFMODE, - .tdf_cycles = 3, -}, { - .ncs_read_setup = 0, - .nrd_setup = 0, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 8, - .nrd_pulse = 8, - .ncs_write_pulse = 5, - .nwe_pulse = 4, - - .read_cycle = 8, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE - | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT - | AT91_SMC_DBW_16 | AT91_SMC_PS_8 - | AT91_SMC_TDFMODE, - .tdf_cycles = 1, -} }; - -static void __init add_device_pcontrol(void) -{ - /* configure chip-select 4 (IO compatible to 8051 X4 ) */ - sam9_smc_configure(0, 4, &pcontrol_smc_config[0]); - /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */ - sam9_smc_configure(0, 7, &pcontrol_smc_config[1]); -} - - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - - -/* - * USB Device port - */ -static struct at91_udc_data __initdata pcontrol_g20_udc_data = { - .vbus_pin = AT91_PIN_PA22, /* Detect +5V bus voltage */ - .pullup_pin = AT91_PIN_PA4, /* K-state, active low */ -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata macb_data = { - .phy_irq_pin = AT91_PIN_PA28, - .is_rmii = 1, -}; - - -/* - * I2C devices: eeprom and phy/switch - */ -static struct i2c_board_info __initdata pcontrol_g20_i2c_devices[] = { -{ /* D7 address width=2, 8KiB */ - I2C_BOARD_INFO("24c64", 0x50) -}, { /* D8 address width=1, 1 byte has 32 bits! */ - I2C_BOARD_INFO("lan9303", 0x0a) -}, }; - - -/* - * LEDs - */ -static struct gpio_led pcontrol_g20_leds[] = { - { - .name = "LED1", /* red H5 */ - .gpio = AT91_PIN_PB18, - .active_low = 1, - .default_trigger = "none", /* supervisor */ - }, { - .name = "LED2", /* yellow H7 */ - .gpio = AT91_PIN_PB19, - .active_low = 1, - .default_trigger = "mmc0", /* SD-card activity */ - }, { - .name = "LED3", /* green H2 */ - .gpio = AT91_PIN_PB20, - .active_low = 1, - .default_trigger = "heartbeat", /* blinky */ - }, { - .name = "LED4", /* red H3 */ - .gpio = AT91_PIN_PC6, - .active_low = 1, - .default_trigger = "none", /* connection lost */ - }, { - .name = "LED5", /* yellow H6 */ - .gpio = AT91_PIN_PC7, - .active_low = 1, - .default_trigger = "none", /* unsent data */ - }, { - .name = "LED6", /* green H1 */ - .gpio = AT91_PIN_PC9, - .active_low = 1, - .default_trigger = "none", /* snafu */ - } -}; - - -/* - * SPI devices - */ -static struct spi_board_info pcontrol_g20_spi_devices[] = { - { - .modalias = "spidev", /* HMI port X4 */ - .chip_select = 1, - .max_speed_hz = 50 * 1000 * 1000, - .bus_num = 0, - }, { - .modalias = "spidev", /* piggyback A2 */ - .chip_select = 0, - .max_speed_hz = 50 * 1000 * 1000, - .bus_num = 1, - }, -}; - - -static void __init pcontrol_g20_board_init(void) -{ - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS - | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ - at91_register_uart(AT91SAM9260_ID_US4, 3, 0); - stamp9g20_board_init(); - at91_add_device_usbh(&usbh_data); - at91_add_device_eth(&macb_data); - at91_add_device_i2c(pcontrol_g20_i2c_devices, - ARRAY_SIZE(pcontrol_g20_i2c_devices)); - add_device_pcontrol(); - at91_add_device_spi(pcontrol_g20_spi_devices, - ARRAY_SIZE(pcontrol_g20_spi_devices)); - at91_add_device_udc(&pcontrol_g20_udc_data); - at91_gpio_leds(pcontrol_g20_leds, - ARRAY_SIZE(pcontrol_g20_leds)); - /* piggyback A2 */ - at91_set_gpio_output(AT91_PIN_PB31, 1); -} - - -MACHINE_START(PCONTROL_G20, "PControl G20") - /* Maintainer: pgsellmann@portner-elektronik.at */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = pcontrol_g20_init_early, - .init_irq = at91_init_irq_default, - .init_machine = pcontrol_g20_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-picotux200.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-picotux200.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-picotux200.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Kleinhenz Elektronik GmbH - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/mtd/physmap.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init picotux200_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata picotux200_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata picotux200_usbh_data = { - .ports = 1, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct mci_platform_data __initdata picotux200_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PB27, - .wp_pin = AT91_PIN_PA17, - }, -}; - -#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 -#define PICOTUX200_FLASH_SIZE SZ_4M - -static struct physmap_flash_data picotux200_flash_data = { - .width = 2, -}; - -static struct resource picotux200_flash_resource = { - .start = PICOTUX200_FLASH_BASE, - .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device picotux200_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &picotux200_flash_data, - }, - .resource = &picotux200_flash_resource, - .num_resources = 1, -}; - -static void __init picotux200_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&picotux200_eth_data); - /* USB Host */ - at91_add_device_usbh(&picotux200_usbh_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* MMC */ - at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ - at91_add_device_mci(0, &picotux200_mci0_data); - /* NOR Flash */ - platform_device_register(&picotux200_flash); -} - -MACHINE_START(PICOTUX2XX, "picotux 200") - /* Maintainer: Kleinhenz Elektronik GmbH */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = picotux200_init_early, - .init_irq = at91_init_irq_default, - .init_machine = picotux200_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-rm9200ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-rm9200ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-rm9200ek.c - * - * Copyright (C) 2005 SAN People - * - * Epson S1D framebuffer glue code is: - * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/mtd/physmap.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -static struct macb_platform_data __initdata ek_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PD4, - .pullup_pin = AT91_PIN_PD5, -}; - -#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD -static struct mci_platform_data __initdata ek_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PB27, - .wp_pin = AT91_PIN_PA17, - } -}; -#endif - -static struct spi_board_info ek_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - }, -#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 3, - .max_speed_hz = 15 * 1000 * 1000, - }, -#endif -}; - -static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("ics1523", 0x26), - }, - { - I2C_BOARD_INFO("dac3550", 0x4d), - } -}; - -#define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE SZ_8M - -static struct physmap_flash_data ek_flash_data = { - .width = 2, -}; - -static struct resource ek_flash_resource = { - .start = EK_FLASH_BASE, - .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ek_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ek_flash_data, - }, - .resource = &ek_flash_resource, - .num_resources = 1, -}; - -static struct gpio_led ek_leds[] = { - { /* "user led 1", DS2 */ - .name = "green", - .gpio = AT91_PIN_PB0, - .active_low = 1, - .default_trigger = "mmc0", - }, - { /* "user led 2", DS4 */ - .name = "yellow", - .gpio = AT91_PIN_PB1, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* "user led 3", DS6 */ - .name = "red", - .gpio = AT91_PIN_PB2, - .active_low = 1, - } -}; - -static void __init ek_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&ek_eth_data); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - at91_set_multi_drive(ek_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ - /* I2C */ - at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); -#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD - /* DataFlash card */ - at91_set_gpio_output(AT91_PIN_PB22, 0); -#else - /* MMC */ - at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ - at91_add_device_mci(0, &ek_mci0_data); -#endif - /* NOR Flash */ - platform_device_register(&ek_flash); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* VGA */ -// ek_add_device_video(); -} - -MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") - /* Maintainer: SAN People/Atmel */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9260ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9260ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-sam9260ek.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/at73c213.h> -#include <linux/clk.h> -#include <linux/platform_data/at24.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * Audio - */ -static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, - .shortname = "AT91SAM9260-EK external DAC", -}; - -#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) -static void __init at73c213_set_clk(struct at73c213_board_info *info) -{ - struct clk *pck0; - struct clk *plla; - - pck0 = clk_get(NULL, "pck0"); - plla = clk_get(NULL, "plla"); - - /* AT73C213 MCK Clock */ - at91_set_B_periph(AT91_PIN_PC1, 0); /* PCK0 */ - - clk_set_parent(pck0, plla); - clk_put(plla); - - info->dac_clk = pck0; -} -#else -static void __init at73c213_set_clk(struct at73c213_board_info *info) {} -#endif - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if !IS_ENABLED(CONFIG_MMC_ATMELMCI) - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#endif -#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) - { /* AT73C213 DAC */ - .modalias = "at73c213", - .chip_select = 0, - .max_speed_hz = 10 * 1000 * 1000, - .bus_num = 1, - .mode = SPI_MODE_1, - .platform_data = &at73c213_data, - }, -#endif -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PA7, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Partition 1", - .offset = 0, - .size = SZ_256K, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata ek_mci0_data = { - .slot[1] = { - .bus_width = 4, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* "bottom" led, green, userled1 to be defined */ - .name = "ds5", - .gpio = AT91_PIN_PA6, - .active_low = 1, - .default_trigger = "none", - }, - { /* "power" led, yellow */ - .name = "ds1", - .gpio = AT91_PIN_PA9, - .default_trigger = "heartbeat", - } -}; - -/* - * I2C devices - */ -static struct at24_platform_data at24c512 = { - .byte_len = SZ_512K / 8, - .page_size = 128, - .flags = AT24_FLAG_ADDR16, -}; - -static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50), - .platform_data = &at24c512, - }, - /* more devices can be added using expansion connectors */ -}; - - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PA30, - .code = BTN_3, - .desc = "Button 3", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA31, - .code = BTN_4, - .desc = "Button 4", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ - at91_set_deglitch(AT91_PIN_PA30, 1); - at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ - at91_set_deglitch(AT91_PIN_PA31, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* NAND */ - ek_add_device_nand(); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* MMC */ - at91_add_device_mci(0, &ek_mci0_data); - /* I2C */ - at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); - /* SSC (to AT73C213) */ - at73c213_set_clk(&at73c213_data); - at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* Push Buttons */ - ek_add_device_buttons(); -} - -MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9261ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9261ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-sam9261ek.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/spi/at73c213.h> -#include <linux/clk.h> -#include <linux/dm9000.h> -#include <linux/fb.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * DM9000 ethernet device - */ -#if defined(CONFIG_DM9000) -static struct resource dm9000_resource[] = { - [0] = { - .start = AT91_CHIPSELECT_2, - .end = AT91_CHIPSELECT_2 + 3, - .flags = IORESOURCE_MEM - }, - [1] = { - .start = AT91_CHIPSELECT_2 + 0x44, - .end = AT91_CHIPSELECT_2 + 0xFF, - .flags = IORESOURCE_MEM - }, - [2] = { - .flags = IORESOURCE_IRQ - | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, - } -}; - -static struct dm9000_plat_data dm9000_platdata = { - .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, -}; - -static struct platform_device dm9000_device = { - .name = "dm9000", - .id = 0, - .num_resources = ARRAY_SIZE(dm9000_resource), - .resource = dm9000_resource, - .dev = { - .platform_data = &dm9000_platdata, - } -}; - -/* - * SMC timings for the DM9000. - * Note: These timings were calculated for MASTER_CLOCK = 100000000 according to the DM9000 timings. - */ -static struct sam9_smc_config __initdata dm9000_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 8, - .nrd_pulse = 4, - .ncs_write_pulse = 8, - .nwe_pulse = 4, - - .read_cycle = 16, - .write_cycle = 16, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16, - .tdf_cycles = 1, -}; - -static void __init ek_add_device_dm9000(void) -{ - struct resource *r = &dm9000_resource[2]; - - /* Configure chip-select 2 (DM9000) */ - sam9_smc_configure(0, 2, &dm9000_smc_config); - - /* Configure Reset signal as output */ - at91_set_gpio_output(AT91_PIN_PC10, 0); - - /* Configure Interrupt pin as input, no pull-up */ - at91_set_gpio_input(AT91_PIN_PC11, 0); - - r->start = r->end = gpio_to_irq(AT91_PIN_PC11); - platform_device_register(&dm9000_device); -} -#else -static void __init ek_add_device_dm9000(void) {} -#endif /* CONFIG_DM9000 */ - - -/* - * USB Host Port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - - -/* - * USB Device Port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PB29, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Partition 1", - .offset = 0, - .size = SZ_256K, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 22, - .cle = 21, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC15, - .enable_pin = AT91_PIN_PC14, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - -/* - * SPI related devices - */ -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) - -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init ek_add_device_ts(void) -{ - at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */ - at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */ -} -#else -static void __init ek_add_device_ts(void) {} -#endif - -/* - * Audio - */ -static struct at73c213_board_info at73c213_data = { - .ssc_id = 1, - .shortname = "AT91SAM9261/9G10-EK external DAC", -}; - -#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) -static void __init at73c213_set_clk(struct at73c213_board_info *info) -{ - struct clk *pck2; - struct clk *plla; - - pck2 = clk_get(NULL, "pck2"); - plla = clk_get(NULL, "plla"); - - /* AT73C213 MCK Clock */ - at91_set_B_periph(AT91_PIN_PB31, 0); /* PCK2 */ - - clk_set_parent(pck2, plla); - clk_put(plla); - - info->dac_clk = pck2; -} -#else -static void __init at73c213_set_clk(struct at73c213_board_info *info) {} -#endif - -/* - * SPI devices - */ -static struct spi_board_info ek_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 2, - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0, - .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ - }, -#endif -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ - .modalias = "mtd_dataflash", - .chip_select = 3, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) - { /* AT73C213 DAC */ - .modalias = "at73c213", - .chip_select = 3, - .max_speed_hz = 10 * 1000 * 1000, - .bus_num = 0, - .mode = SPI_MODE_1, - .platform_data = &at73c213_data, - .controller_data = (void*) AT91_PIN_PA29, /* default for CS3 is PA6, but it must be PA29 */ - }, -#endif -}; - -#else /* CONFIG_SPI_ATMEL_* */ -/* spi0 and mmc/sd share the same PIO pins: cannot be used at the same time */ - -/* - * MCI (SD/MMC) - * det_pin, wp_pin and vcc_pin are not connected - */ -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - -#endif /* CONFIG_SPI_ATMEL_* */ - - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) - -#if defined(CONFIG_FB_ATMEL_STN) - -/* STN */ -static struct fb_videomode at91_stn_modes[] = { - { - .name = "SP06Q002 @ 75", - .refresh = 75, - .xres = 320, .yres = 240, - .pixclock = KHZ2PICOS(1440), - - .left_margin = 1, .right_margin = 1, - .upper_margin = 0, .lower_margin = 0, - .hsync_len = 1, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_stn_monspecs = { - .manufacturer = "HIT", - .monitor = "SP06Q002", - - .modedb = at91_stn_modes, - .modedb_len = ARRAY_SIZE(at91_stn_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91SAM9261_DEFAULT_STN_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_STNMONO \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \ - | ATMEL_LCDC_IFWIDTH_4 \ - | ATMEL_LCDC_SCANMOD_SINGLE) - -static void at91_lcdc_stn_power_control(struct atmel_lcdfb_pdata *pdata, int on) -{ - /* backlight */ - if (on) { /* power up */ - at91_set_gpio_value(AT91_PIN_PC14, 0); - at91_set_gpio_value(AT91_PIN_PC15, 0); - } else { /* power down */ - at91_set_gpio_value(AT91_PIN_PC14, 1); - at91_set_gpio_value(AT91_PIN_PC15, 1); - } -} - -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { - .default_bpp = 1, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2, - .default_monspecs = &at91fb_default_stn_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, - .guard_time = 1, -}; - -#else - -/* TFT */ -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "TX09D50VM1CCA @ 60", - .refresh = 60, - .xres = 240, .yres = 320, - .pixclock = KHZ2PICOS(4965), - - .left_margin = 1, .right_margin = 33, - .upper_margin = 1, .lower_margin = 0, - .hsync_len = 5, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_tft_monspecs = { - .manufacturer = "HIT", - .monitor = "TX09D50VM1CCA", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -static void at91_lcdc_tft_power_control(struct atmel_lcdfb_pdata *pdata, int on) -{ - if (on) - at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ - else - at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ -} - -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, - .default_monspecs = &at91fb_default_tft_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, - .guard_time = 1, -}; -#endif - -#else -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; -#endif - - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PA27, - .code = BTN_0, - .desc = "Button 0", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA26, - .code = BTN_1, - .desc = "Button 1", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA25, - .code = BTN_2, - .desc = "Button 2", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA24, - .code = BTN_3, - .desc = "Button 3", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA27, 1); /* btn0 */ - at91_set_deglitch(AT91_PIN_PA27, 1); - at91_set_gpio_input(AT91_PIN_PA26, 1); /* btn1 */ - at91_set_deglitch(AT91_PIN_PA26, 1); - at91_set_gpio_input(AT91_PIN_PA25, 1); /* btn2 */ - at91_set_deglitch(AT91_PIN_PA25, 1); - at91_set_gpio_input(AT91_PIN_PA24, 1); /* btn3 */ - at91_set_deglitch(AT91_PIN_PA24, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* "bottom" led, green, userled1 to be defined */ - .name = "ds7", - .gpio = AT91_PIN_PA14, - .active_low = 1, - .default_trigger = "none", - }, - { /* "top" led, green, userled2 to be defined */ - .name = "ds8", - .gpio = AT91_PIN_PA13, - .active_low = 1, - .default_trigger = "none", - }, - { /* "power" led, yellow */ - .name = "ds1", - .gpio = AT91_PIN_PA23, - .default_trigger = "heartbeat", - } -}; - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - - if (cpu_is_at91sam9g10()) - ek_lcdc_data.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB; - - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* NAND */ - ek_add_device_nand(); - /* DM9000 ethernet */ - ek_add_device_dm9000(); - - /* spi0 and mmc/sd share the same PIO pins */ -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* Touchscreen */ - ek_add_device_ts(); - /* SSC (to AT73C213) */ - at73c213_set_clk(&at73c213_data); - at91_add_device_ssc(AT91SAM9261_ID_SSC1, ATMEL_SSC_TX); -#else - /* MMC */ - at91_add_device_mci(0, &mci0_data); -#endif - /* LCD Controller */ - at91_add_device_lcdc(&ek_lcdc_data); - /* Push Buttons */ - ek_add_device_buttons(); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); -} - -MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END - -MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9263ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9263ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-sam9263ek.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Atmel Corporation. - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/platform_data/at24.h> -#include <linux/fb.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/leds.h> -#include <linux/pwm.h> -#include <linux/leds_pwm.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 16.367 MHz crystal */ - at91_initialize(16367660); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, - .vbus_pin_active_low = {1, 1}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PA25, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init ek_add_device_ts(void) -{ - at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */ - at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */ -} -#else -static void __init ek_add_device_ts(void) {} -#endif - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 3, - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, - }, -#endif -}; - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata mci1_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PE18, - .wp_pin = AT91_PIN_PE19, - }, -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PE31, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Partition 1", - .offset = 0, - .size = SZ_64M, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PA22, - .enable_pin = AT91_PIN_PD15, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * I2C devices - */ -static struct at24_platform_data at24c512 = { - .byte_len = SZ_512K / 8, - .page_size = 128, - .flags = AT24_FLAG_ADDR16, -}; - - -static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50), - .platform_data = &at24c512, - }, - /* more devices can be added using expansion connectors */ -}; - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "TX09D50VM1CCA @ 60", - .refresh = 60, - .xres = 240, .yres = 320, - .pixclock = KHZ2PICOS(4965), - - .left_margin = 1, .right_margin = 33, - .upper_margin = 1, .lower_margin = 0, - .hsync_len = 5, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_monspecs = { - .manufacturer = "HIT", - .monitor = "TX09D70VM1CCA", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -static void at91_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) -{ - at91_set_gpio_value(AT91_PIN_PA30, on); -} - -/* Driver datas */ -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, - .default_monspecs = &at91fb_default_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_power_control, - .guard_time = 1, -}; - -#else -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; -#endif - - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { /* BP1, "leftclic" */ - .code = BTN_LEFT, - .gpio = AT91_PIN_PC5, - .active_low = 1, - .desc = "left_click", - .wakeup = 1, - }, - { /* BP2, "rightclic" */ - .code = BTN_RIGHT, - .gpio = AT91_PIN_PC4, - .active_low = 1, - .desc = "right_click", - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_GPIO_periph(AT91_PIN_PC5, 1); /* left button */ - at91_set_deglitch(AT91_PIN_PC5, 1); - at91_set_GPIO_periph(AT91_PIN_PC4, 1); /* right button */ - at91_set_deglitch(AT91_PIN_PC4, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - -/* - * AC97 - * reset_pin is not connected: NRST - */ -static struct ac97c_platform_data ek_ac97_data = { - .reset_pin = -EINVAL, -}; - - -/* - * LEDs ... these could all be PWM-driven, for variable brightness - */ -static struct gpio_led ek_leds[] = { - { /* "right" led, green, userled2 (could be driven by pwm2) */ - .name = "ds2", - .gpio = AT91_PIN_PC29, - .active_low = 1, - .default_trigger = "nand-disk", - }, - { /* "power" led, yellow (could be driven by pwm0) */ - .name = "ds3", - .gpio = AT91_PIN_PB7, - .default_trigger = "heartbeat", - }, -#if !IS_ENABLED(CONFIG_LEDS_PWM) - { - .name = "ds1", - .gpio = AT91_PIN_PB8, - .active_low = 1, - .default_trigger = "none", - } -#endif -}; - -/* - * PWM Leds - */ -static struct pwm_lookup pwm_lookup[] = { - PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "ds1", - 5000, PWM_POLARITY_INVERSED), -}; - -#if IS_ENABLED(CONFIG_LEDS_PWM) -static struct led_pwm pwm_leds[] = { - { - .name = "ds1", - .max_brightness = 255, - }, -}; - -static struct led_pwm_platform_data pwm_data = { - .num_leds = ARRAY_SIZE(pwm_leds), - .leds = pwm_leds, -}; - -static struct platform_device leds_pwm = { - .name = "leds_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_data, - }, -}; -#endif - - -/* - * CAN - */ -static void sam9263ek_transceiver_switch(int on) -{ - if (on) { - at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */ - at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */ - } else { - at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */ - at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */ - } -} - -static struct at91_can_data ek_can_data = { - .transceiver_switch = sam9263ek_transceiver_switch, -}; - -static struct platform_device *devices[] __initdata = { -#if IS_ENABLED(CONFIG_LEDS_PWM) - &leds_pwm, -#endif -}; - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* Touchscreen */ - ek_add_device_ts(); - /* MMC */ - at91_add_device_mci(1, &mci1_data); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* NAND */ - ek_add_device_nand(); - /* I2C */ - at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); - /* LCD Controller */ - at91_add_device_lcdc(&ek_lcdc_data); - /* Push Buttons */ - ek_add_device_buttons(); - /* AC97 */ - at91_add_device_ac97(&ek_ac97_data); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); -#if IS_ENABLED(CONFIG_LEDS_PWM) - at91_add_device_pwm(1 << AT91_PWM1); -#endif - /* CAN */ - at91_add_device_can(&ek_can_data); - /* Other platform devices */ - platform_add_devices(devices, ARRAY_SIZE(devices)); -} - -MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9g20ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9g20ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2005 SAN People - * Copyright (C) 2008 Atmel - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/at73c213.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/clk.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/consumer.h> - -#include <linux/platform_data/at91_adc.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - -/* - * board revision encoding - * bit 0: - * 0 => 1 sd/mmc slot - * 1 => 2 sd/mmc slots connectors (board from revision C) - */ -#define HAVE_2MMC (1 << 0) -static int inline ek_have_2mmc(void) -{ - return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC); -} - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if !IS_ENABLED(CONFIG_MMC_ATMELMCI) - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#endif -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PA7, - .is_rmii = 1, -}; - -static void __init ek_add_device_macb(void) -{ - if (ek_have_2mmc()) - ek_macb_data.phy_irq_pin = AT91_PIN_PB0; - - at91_add_device_eth(&ek_macb_data); -} - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Bootstrap", - .offset = 0, - .size = 4 * SZ_1M, - }, - { - .name = "Partition 1", - .offset = MTDPART_OFS_NXTBLK, - .size = 60 * SZ_1M, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -/* det_pin is not connected */ -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .det_pin = -EINVAL, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 3, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * MCI (SD/MMC) - * wp_pin and vcc_pin are not connected - */ -static struct mci_platform_data __initdata ek_mmc_data = { - .slot[1] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC9, - .wp_pin = -EINVAL, - }, - -}; - -static void __init ek_add_device_mmc(void) -{ - if (ek_have_2mmc()) { - ek_mmc_data.slot[0].bus_width = 4; - ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; - ek_mmc_data.slot[0].wp_pin = -1; - } - at91_add_device_mci(0, &ek_mmc_data); -} - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* "bottom" led, green, userled1 to be defined */ - .name = "ds5", - .gpio = AT91_PIN_PA6, - .active_low = 1, - .default_trigger = "none", - }, - { /* "power" led, yellow */ - .name = "ds1", - .gpio = AT91_PIN_PA9, - .default_trigger = "heartbeat", - } -}; - -static void __init ek_add_device_gpio_leds(void) -{ - if (ek_have_2mmc()) { - ek_leds[0].gpio = AT91_PIN_PB8; - ek_leds[1].gpio = AT91_PIN_PB9; - } - - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); -} - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PA30, - .code = BTN_3, - .desc = "Button 3", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA31, - .code = BTN_4, - .desc = "Button 4", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ - at91_set_deglitch(AT91_PIN_PA30, 1); - at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ - at91_set_deglitch(AT91_PIN_PA31, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - -/* - * ADCs - */ - -static struct at91_adc_data ek_adc_data = { - .channels_used = BIT(0) | BIT(1) | BIT(2) | BIT(3), - .use_external_triggers = true, - .vref = 3300, -}; - -#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE) -static struct regulator_consumer_supply ek_audio_consumer_supplies[] = { - REGULATOR_SUPPLY("AVDD", "0-001b"), - REGULATOR_SUPPLY("HPVDD", "0-001b"), - REGULATOR_SUPPLY("DBVDD", "0-001b"), - REGULATOR_SUPPLY("DCVDD", "0-001b"), -}; - -static struct regulator_init_data ek_avdd_reg_init_data = { - .constraints = { - .name = "3V3", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = ek_audio_consumer_supplies, - .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies), -}; - -static struct fixed_voltage_config ek_vdd_pdata = { - .supply_name = "board-3V3", - .microvolts = 3300000, - .gpio = -EINVAL, - .enabled_at_boot = 0, - .init_data = &ek_avdd_reg_init_data, -}; -static struct platform_device ek_voltage_regulator = { - .name = "reg-fixed-voltage", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_vdd_pdata, - }, -}; -static void __init ek_add_regulators(void) -{ - platform_device_register(&ek_voltage_regulator); -} -#else -static void __init ek_add_regulators(void) {} -#endif - - -static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50) - }, - { - I2C_BOARD_INFO("wm8731", 0x1b) - }, -}; - -static struct platform_device sam9g20ek_audio_device = { - .name = "at91sam9g20ek-audio", - .id = -1, -}; - -static void __init ek_add_device_audio(void) -{ - platform_device_register(&sam9g20ek_audio_device); -} - - -static void __init ek_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* NAND */ - ek_add_device_nand(); - /* Ethernet */ - ek_add_device_macb(); - /* Regulators */ - ek_add_regulators(); - /* MMC */ - ek_add_device_mmc(); - /* I2C */ - at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); - /* LEDs */ - ek_add_device_gpio_leds(); - /* Push Buttons */ - ek_add_device_buttons(); - /* ADCs */ - at91_add_device_adc(&ek_adc_data); - /* PCK0 provides MCLK to the WM8731 */ - at91_set_B_periph(AT91_PIN_PC1, 0); - /* SSC (for WM8731) */ - at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); - ek_add_device_audio(); -} - -MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END - -MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9-l9260.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9-l9260.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-sam9-l9260.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * Copyright (C) 2007 Olimex 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. - * - * 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 <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91sam9_smc.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if !IS_ENABLED(CONFIG_MMC_ATMELMCI) - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#endif -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PA7, - .is_rmii = 0, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Bootloader Area", - .offset = 0, - .size = 10 * SZ_1M, - }, - { - .name = "User Area", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .ecc_mode = NAND_ECC_SOFT, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata ek_mci0_data = { - .slot[1] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC8, - .wp_pin = AT91_PIN_PC4, - }, -}; - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* D1 */ - .name = "led1", - .gpio = AT91_PIN_PA9, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* D2 */ - .name = "led2", - .gpio = AT91_PIN_PA6, - .active_low = 1, - .default_trigger = "timer", - } -}; - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* NAND */ - ek_add_device_nand(); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* MMC */ - at91_add_device_mci(0, &ek_mci0_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); -} - -MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") - /* Maintainer: Olimex */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9m10g45ek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9m10g45ek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family - * - * Covers: * AT91SAM9G45-EKES board - * * AT91SAM9M10G45-EK board - * - * Copyright (C) 2009 Atmel Corporation. - * - * 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. - * - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/fb.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/leds.h> -#include <linux/atmel-mci.h> -#include <linux/delay.h> -#include <linux/pwm.h> -#include <linux/leds_pwm.h> - -#include <linux/platform_data/at91_adc.h> - -#include <mach/hardware.h> -#include <video/atmel_lcdc.h> -#include <media/soc_camera.h> -#include <media/atmel-isi.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 12.000 MHz crystal */ - at91_initialize(12000000); -} - -/* - * USB HS Host port (common to OHCI & EHCI) - */ -static struct at91_usbh_data __initdata ek_usbh_hs_data = { - .ports = 2, - .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, - .vbus_pin_active_low = {1, 1}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - - -/* - * USB HS Device port - */ -static struct usba_platform_data __initdata ek_usba_udc_data = { - .vbus_pin = AT91_PIN_PB19, -}; - - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -}; - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PD10, - .wp_pin = -EINVAL, - }, -}; - -static struct mci_platform_data __initdata mci1_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PD11, - .wp_pin = AT91_PIN_PD29, - }, -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PD5, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Partition 1", - .offset = 0, - .size = SZ_64M, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -/* det_pin is not connected */ -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC8, - .enable_pin = AT91_PIN_PC14, - .det_pin = -EINVAL, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 3, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * ISI - */ -static struct isi_platform_data __initdata isi_data = { - .frate = ISI_CFG1_FRATE_CAPTURE_ALL, - /* to use codec and preview path simultaneously */ - .full_mode = 1, - .data_width_flags = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10, - /* ISI_MCK is provided by programmable clock or external clock */ - .mck_hz = 25000000, -}; - - -/* - * soc-camera OV2640 - */ -#if defined(CONFIG_SOC_CAMERA_OV2640) || \ - defined(CONFIG_SOC_CAMERA_OV2640_MODULE) -static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link) -{ - /* ISI board for ek using default 8-bits connection */ - return SOCAM_DATAWIDTH_8; -} - -static int i2c_camera_power(struct device *dev, int on) -{ - /* enable or disable the camera */ - pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE"); - at91_set_gpio_output(AT91_PIN_PD13, !on); - - if (!on) - goto out; - - /* If enabled, give a reset impulse */ - at91_set_gpio_output(AT91_PIN_PD12, 0); - msleep(20); - at91_set_gpio_output(AT91_PIN_PD12, 1); - msleep(100); - -out: - return 0; -} - -static struct i2c_board_info i2c_camera = { - I2C_BOARD_INFO("ov2640", 0x30), -}; - -static struct soc_camera_link iclink_ov2640 = { - .bus_id = 0, - .board_info = &i2c_camera, - .i2c_adapter_id = 0, - .power = i2c_camera_power, - .query_bus_param = isi_camera_query_bus_param, -}; - -static struct platform_device isi_ov2640 = { - .name = "soc-camera-pdrv", - .id = 0, - .dev = { - .platform_data = &iclink_ov2640, - }, -}; -#endif - - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "LG", - .refresh = 60, - .xres = 480, .yres = 272, - .pixclock = KHZ2PICOS(9000), - - .left_margin = 1, .right_margin = 1, - .upper_margin = 40, .lower_margin = 1, - .hsync_len = 45, .vsync_len = 1, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_monspecs = { - .manufacturer = "LG", - .monitor = "LB043WQ1", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 17640, - .vfmin = 57, - .vfmax = 67, -}; - -#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -/* Driver datas */ -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, - .default_bpp = 32, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2, - .default_monspecs = &at91fb_default_monspecs, - .guard_time = 9, - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, -}; - -#else -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; -#endif - - -/* - * ADCs and touchscreen - */ -static struct at91_adc_data ek_adc_data = { - .channels_used = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7), - .use_external_triggers = true, - .vref = 3300, - .touchscreen_type = ATMEL_ADC_TOUCHSCREEN_4WIRE, -}; - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { /* BP1, "leftclic" */ - .code = BTN_LEFT, - .gpio = AT91_PIN_PB6, - .active_low = 1, - .desc = "left_click", - .wakeup = 1, - }, - { /* BP2, "rightclic" */ - .code = BTN_RIGHT, - .gpio = AT91_PIN_PB7, - .active_low = 1, - .desc = "right_click", - .wakeup = 1, - }, - /* BP3, "joystick" */ - { - .code = KEY_LEFT, - .gpio = AT91_PIN_PB14, - .active_low = 1, - .desc = "Joystick Left", - }, - { - .code = KEY_RIGHT, - .gpio = AT91_PIN_PB15, - .active_low = 1, - .desc = "Joystick Right", - }, - { - .code = KEY_UP, - .gpio = AT91_PIN_PB16, - .active_low = 1, - .desc = "Joystick Up", - }, - { - .code = KEY_DOWN, - .gpio = AT91_PIN_PB17, - .active_low = 1, - .desc = "Joystick Down", - }, - { - .code = KEY_ENTER, - .gpio = AT91_PIN_PB18, - .active_low = 1, - .desc = "Joystick Press", - }, -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) { - at91_set_GPIO_periph(ek_buttons[i].gpio, 1); - at91_set_deglitch(ek_buttons[i].gpio, 1); - } - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - -/* - * AC97 - * reset_pin is not connected: NRST - */ -static struct ac97c_platform_data ek_ac97_data = { - .reset_pin = -EINVAL, -}; - - -/* - * LEDs ... these could all be PWM-driven, for variable brightness - */ -static struct gpio_led ek_leds[] = { - { /* "top" led, red, powerled */ - .name = "d8", - .gpio = AT91_PIN_PD30, - .default_trigger = "heartbeat", - }, - { /* "left" led, green, userled2, pwm3 */ - .name = "d6", - .gpio = AT91_PIN_PD0, - .active_low = 1, - .default_trigger = "nand-disk", - }, -#if !IS_ENABLED(CONFIG_LEDS_PWM) - { /* "right" led, green, userled1, pwm1 */ - .name = "d7", - .gpio = AT91_PIN_PD31, - .active_low = 1, - .default_trigger = "mmc0", - }, -#endif -}; - - -/* - * PWM Leds - */ -static struct pwm_lookup pwm_lookup[] = { - PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "d7", - 5000, PWM_POLARITY_INVERSED), -}; - -#if IS_ENABLED(CONFIG_LEDS_PWM) -static struct led_pwm pwm_leds[] = { - { /* "right" led, green, userled1, pwm1 */ - .name = "d7", - .max_brightness = 255, - }, -}; - -static struct led_pwm_platform_data pwm_data = { - .num_leds = ARRAY_SIZE(pwm_leds), - .leds = pwm_leds, -}; - -static struct platform_device leds_pwm = { - .name = "leds_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_data, - }, -}; -#endif - -static struct platform_device *devices[] __initdata = { -#if defined(CONFIG_SOC_CAMERA_OV2640) || \ - defined(CONFIG_SOC_CAMERA_OV2640_MODULE) - &isi_ov2640, -#endif -#if IS_ENABLED(CONFIG_LEDS_PWM) - &leds_pwm, -#endif -}; - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 not connected on the -EK board */ - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB HS Host */ - at91_add_device_usbh_ohci(&ek_usbh_hs_data); - at91_add_device_usbh_ehci(&ek_usbh_hs_data); - /* USB HS Device */ - at91_add_device_usba(&ek_usba_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* MMC */ - at91_add_device_mci(0, &mci0_data); - at91_add_device_mci(1, &mci1_data); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* NAND */ - ek_add_device_nand(); - /* I2C */ - at91_add_device_i2c(0, NULL, 0); - /* ISI, using programmable clock as ISI_MCK */ - at91_add_device_isi(&isi_data, true); - /* LCD Controller */ - at91_add_device_lcdc(&ek_lcdc_data); - /* ADC and touchscreen */ - at91_add_device_adc(&ek_adc_data); - /* Push Buttons */ - ek_add_device_buttons(); - /* AC97 */ - at91_add_device_ac97(&ek_ac97_data); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); -#if IS_ENABLED(CONFIG_LEDS_PWM) - at91_add_device_pwm(1 << AT91_PWM1); -#endif - /* Other platform devices */ - platform_add_devices(devices, ARRAY_SIZE(devices)); -} - -MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-sam9rlek.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-sam9rlek.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/fb.h> -#include <linux/clk.h> -#include <linux/input.h> -#include <linux/gpio_keys.h> -#include <linux/platform_data/at91_adc.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> - - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 12.000 MHz crystal */ - at91_initialize(12000000); -} - -/* - * USB HS Device port - */ -static struct usba_platform_data __initdata ek_usba_udc_data = { - .vbus_pin = AT91_PIN_PA8, -}; - - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PA15, - .wp_pin = -EINVAL, - }, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Partition 1", - .offset = 0, - .size = SZ_256K, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PD17, - .enable_pin = AT91_PIN_PB6, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * SPI devices - */ -static struct spi_board_info ek_spi_devices[] = { - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -}; - - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "TX09D50VM1CCA @ 60", - .refresh = 60, - .xres = 240, .yres = 320, - .pixclock = KHZ2PICOS(4965), - - .left_margin = 1, .right_margin = 33, - .upper_margin = 1, .lower_margin = 0, - .hsync_len = 5, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_monspecs = { - .manufacturer = "HIT", - .monitor = "TX09D50VM1CCA", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91SAM9RL_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -static void at91_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) -{ - if (on) - at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */ - else - at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */ -} - -/* Driver datas */ -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2, - .default_monspecs = &at91fb_default_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_power_control, - .guard_time = 1, - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, -}; - -#else -static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; -#endif - - -/* - * AC97 - * reset_pin is not connected: NRST - */ -static struct ac97c_platform_data ek_ac97_data = { - .reset_pin = -EINVAL, -}; - - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* "bottom" led, green, userled1 to be defined */ - .name = "ds1", - .gpio = AT91_PIN_PD15, - .active_low = 1, - .default_trigger = "none", - }, - { /* "bottom" led, green, userled2 to be defined */ - .name = "ds2", - .gpio = AT91_PIN_PD16, - .active_low = 1, - .default_trigger = "none", - }, - { /* "power" led, yellow */ - .name = "ds3", - .gpio = AT91_PIN_PD14, - .default_trigger = "heartbeat", - } -}; - - -/* - * ADC + Touchscreen - */ -static struct at91_adc_data ek_adc_data = { - .channels_used = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5), - .use_external_triggers = true, - .vref = 3300, - .touchscreen_type = ATMEL_ADC_TOUCHSCREEN_4WIRE, -}; - - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PB0, - .code = BTN_2, - .desc = "Right Click", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB1, - .code = BTN_1, - .desc = "Left Click", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */ - at91_set_deglitch(AT91_PIN_PB1, 1); - at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */ - at91_set_deglitch(AT91_PIN_PB0, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - -static void __init ek_board_init(void) -{ - at91_register_devices(); - - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB HS */ - at91_add_device_usba(&ek_usba_udc_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* NAND */ - ek_add_device_nand(); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* MMC */ - at91_add_device_mci(0, &mci0_data); - /* LCD Controller */ - at91_add_device_lcdc(&ek_lcdc_data); - /* AC97 */ - at91_add_device_ac97(&ek_ac97_data); - /* Touch Screen Controller + ADC */ - at91_add_device_adc(&ek_adc_data); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* Push Buttons */ - ek_add_device_buttons(); -} - -MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") - /* Maintainer: Atmel */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-snapper9260.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-snapper9260.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-snapper9260.c - * - * Copyright (C) 2010 Bluewater System Ltd - * - * Author: Andre Renaud <andre@bluewatersys.com> - * Author: Ryan Mallon - * - * 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 - * - */ - -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/platform_data/pca953x.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include <mach/hardware.h> -#include <mach/at91sam9_smc.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - -#define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x)) - -static void __init snapper9260_init_early(void) -{ - at91_initialize(18432000); -} - -static struct at91_usbh_data __initdata snapper9260_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -static struct at91_udc_data __initdata snapper9260_udc_data = { - .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5), - .vbus_active_low = 1, - .vbus_polled = 1, - .pullup_pin = -EINVAL, -}; - -static struct macb_platform_data snapper9260_macb_data = { - .phy_irq_pin = -EINVAL, - .is_rmii = 1, -}; - -static struct mtd_partition __initdata snapper9260_nand_partitions[] = { - { - .name = "Preboot", - .offset = 0, - .size = SZ_128K, - }, - { - .name = "Bootloader", - .offset = MTDPART_OFS_APPEND, - .size = SZ_256K, - }, - { - .name = "Environment", - .offset = MTDPART_OFS_APPEND, - .size = SZ_128K, - }, - { - .name = "Kernel", - .offset = MTDPART_OFS_APPEND, - .size = SZ_4M, - }, - { - .name = "Filesystem", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata snapper9260_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .parts = snapper9260_nand_partitions, - .num_parts = ARRAY_SIZE(snapper9260_nand_partitions), - .bus_width_16 = 0, - .enable_pin = -EINVAL, - .det_pin = -EINVAL, - .ecc_mode = NAND_ECC_SOFT, -}; - -static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 0, - .ncs_write_setup = 0, - .nwe_setup = 0, - - .ncs_read_pulse = 5, - .nrd_pulse = 2, - .ncs_write_pulse = 5, - .nwe_pulse = 2, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | - AT91_SMC_EXNWMODE_DISABLE), - .tdf_cycles = 1, -}; - -static struct pca953x_platform_data snapper9260_io_expander_data = { - .gpio_base = SNAPPER9260_IO_EXP_GPIO(0), -}; - -static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { - { - /* IO expander */ - I2C_BOARD_INFO("max7312", 0x28), - .platform_data = &snapper9260_io_expander_data, - }, - { - /* Audio codec */ - I2C_BOARD_INFO("tlv320aic23", 0x1a), - }, -}; - -static struct i2c_board_info __initdata snapper9260_i2c_isl1208 = { - /* RTC */ - I2C_BOARD_INFO("isl1208", 0x6f), -}; - -static void __init snapper9260_add_device_nand(void) -{ - at91_set_A_periph(AT91_PIN_PC14, 0); - sam9_smc_configure(0, 3, &snapper9260_nand_smc_config); - at91_add_device_nand(&snapper9260_nand_data); -} - -static void __init snapper9260_board_init(void) -{ - at91_register_devices(); - - at91_add_device_i2c(snapper9260_i2c_devices, - ARRAY_SIZE(snapper9260_i2c_devices)); - - snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31); - i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1); - - /* Debug on ttyS0 */ - at91_register_uart(0, 0, 0); - - at91_register_uart(AT91SAM9260_ID_US0, 1, - ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_register_uart(AT91SAM9260_ID_US1, 2, - ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_register_uart(AT91SAM9260_ID_US2, 3, 0); - at91_add_device_serial(); - at91_add_device_usbh(&snapper9260_usbh_data); - at91_add_device_udc(&snapper9260_udc_data); - at91_add_device_eth(&snapper9260_macb_data); - at91_add_device_ssc(AT91SAM9260_ID_SSC, (ATMEL_SSC_TF | ATMEL_SSC_TK | - ATMEL_SSC_TD | ATMEL_SSC_RD)); - snapper9260_add_device_nand(); -} - -MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = snapper9260_init_early, - .init_irq = at91_init_irq_default, - .init_machine = snapper9260_board_init, -MACHINE_END - - Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-stamp9g20.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-stamp9g20.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> - * taskit GmbH - * - * 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 - */ - -#include <linux/mm.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/w1-gpio.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include <mach/at91sam9_smc.h> -#include <mach/hardware.h> - -#include "at91_aic.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" -#include "gpio.h" - - -void __init stamp9g20_init_early(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * NAND flash - */ -static struct atmel_nand_data __initdata nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .bus_width_16 = 0, - .det_pin = -EINVAL, - .ecc_mode = NAND_ECC_SOFT, -}; - -static struct sam9_smc_config __initdata nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 3, -}; - -static void __init add_device_nand(void) -{ - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &nand_smc_config); - - at91_add_device_nand(&nand_data); -} - - -/* - * MCI (SD/MMC) - * det_pin, wp_pin and vcc_pin are not connected - */ -static struct mci_platform_data __initdata mmc_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -1, - .wp_pin = -1, - }, -}; - - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - - -/* - * USB Device port - */ -static struct at91_udc_data __initdata portuxg20_udc_data = { - .vbus_pin = AT91_PIN_PC7, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - -static struct at91_udc_data __initdata stamp9g20evb_udc_data = { - .vbus_pin = AT91_PIN_PA22, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata macb_data = { - .phy_irq_pin = AT91_PIN_PA28, - .is_rmii = 1, -}; - - -/* - * LEDs - */ -static struct gpio_led portuxg20_leds[] = { - { - .name = "LED2", - .gpio = AT91_PIN_PC5, - .default_trigger = "none", - }, { - .name = "LED3", - .gpio = AT91_PIN_PC4, - .default_trigger = "none", - }, { - .name = "LED4", - .gpio = AT91_PIN_PC10, - .default_trigger = "heartbeat", - } -}; - -static struct gpio_led stamp9g20evb_leds[] = { - { - .name = "D8", - .gpio = AT91_PIN_PB18, - .active_low = 1, - .default_trigger = "none", - }, { - .name = "D9", - .gpio = AT91_PIN_PB19, - .active_low = 1, - .default_trigger = "none", - }, { - .name = "D10", - .gpio = AT91_PIN_PB20, - .active_low = 1, - .default_trigger = "heartbeat", - } -}; - - -/* - * SPI devices - */ -static struct spi_board_info portuxg20_spi_devices[] = { - { - .modalias = "spidev", - .chip_select = 0, - .max_speed_hz = 1 * 1000 * 1000, - .bus_num = 0, - }, { - .modalias = "spidev", - .chip_select = 0, - .max_speed_hz = 1 * 1000 * 1000, - .bus_num = 1, - }, -}; - - -/* - * Dallas 1-Wire - */ -static struct w1_gpio_platform_data w1_gpio_pdata = { - .pin = AT91_PIN_PA29, - .is_open_drain = 1, - .ext_pullup_enable_pin = -EINVAL, -}; - -static struct platform_device w1_device = { - .name = "w1-gpio", - .id = -1, - .dev.platform_data = &w1_gpio_pdata, -}; - -void add_w1(void) -{ - at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); - at91_set_multi_drive(w1_gpio_pdata.pin, 1); - platform_device_register(&w1_device); -} - - -void __init stamp9g20_board_init(void) -{ - /* Serial */ - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - at91_add_device_serial(); - /* NAND */ - add_device_nand(); - /* MMC */ - at91_add_device_mci(0, &mmc_data); - /* W1 */ - add_w1(); -} - -static void __init portuxg20_board_init(void) -{ - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART4 on ttyS5. (Rx, Tx only) */ - at91_register_uart(AT91SAM9260_ID_US4, 5, 0); - - /* USART5 on ttyS6. (Rx, Tx only) */ - at91_register_uart(AT91SAM9260_ID_US5, 6, 0); - stamp9g20_board_init(); - /* USB Host */ - at91_add_device_usbh(&usbh_data); - /* USB Device */ - at91_add_device_udc(&portuxg20_udc_data); - /* Ethernet */ - at91_add_device_eth(&macb_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* SPI */ - at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); - /* LEDs */ - at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); -} - -static void __init stamp9g20evb_board_init(void) -{ - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR - | ATMEL_UART_DCD | ATMEL_UART_RI); - stamp9g20_board_init(); - /* USB Host */ - at91_add_device_usbh(&usbh_data); - /* USB Device */ - at91_add_device_udc(&stamp9g20evb_udc_data); - /* Ethernet */ - at91_add_device_eth(&macb_data); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* LEDs */ - at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds)); -} - -MACHINE_START(PORTUXG20, "taskit PortuxG20") - /* Maintainer: taskit GmbH */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = stamp9g20_init_early, - .init_irq = at91_init_irq_default, - .init_machine = portuxg20_board_init, -MACHINE_END - -MACHINE_START(STAMP9G20, "taskit Stamp9G20") - /* Maintainer: taskit GmbH */ - .init_time = at91_init_time, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = stamp9g20_init_early, - .init_irq = at91_init_irq_default, - .init_machine = stamp9g20evb_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/board-yl-9200.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/board-yl-9200.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/board-yl-9200.c - * - * Adapted from various board files in arch/arm/mach-at91 - * - * Modifications for YL-9200 platform: - * Copyright (C) 2007 S. Birtles - * - * 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 - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/mtd/physmap.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/hardware.h> -#include <mach/at91rm9200_mc.h> -#include <mach/at91_ramc.h> -#include <mach/cpu.h> - -#include "at91_aic.h" -#include "board.h" -#include "generic.h" -#include "gpio.h" - - -static void __init yl9200_init_early(void) -{ - /* Set cpu type: PQFP */ - at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - - /* Initialize processor: 18.432 MHz crystal */ - at91_initialize(18432000); -} - -/* - * LEDs - */ -static struct gpio_led yl9200_leds[] = { - { /* D2 */ - .name = "led2", - .gpio = AT91_PIN_PB17, - .active_low = 1, - .default_trigger = "timer", - }, - { /* D3 */ - .name = "led3", - .gpio = AT91_PIN_PB16, - .active_low = 1, - .default_trigger = "heartbeat", - }, - { /* D4 */ - .name = "led4", - .gpio = AT91_PIN_PB15, - .active_low = 1, - }, - { /* D5 */ - .name = "led5", - .gpio = AT91_PIN_PB8, - .active_low = 1, - } -}; - -/* - * Ethernet - */ -static struct macb_platform_data __initdata yl9200_eth_data = { - .phy_irq_pin = AT91_PIN_PB28, - .is_rmii = 1, -}; - -/* - * USB Host - */ -static struct at91_usbh_data __initdata yl9200_usbh_data = { - .ports = 1, /* PQFP version of AT91RM9200 */ - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device - */ -static struct at91_udc_data __initdata yl9200_udc_data = { - .pullup_pin = AT91_PIN_PC4, - .vbus_pin = AT91_PIN_PC5, - .pullup_active_low = 1, /* Active Low due to PNP transistor (pg 7) */ - -}; - -/* - * MMC - */ -static struct mci_platform_data __initdata yl9200_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PB9, - .wp_pin = -EINVAL, - }, -}; - -/* - * NAND Flash - */ -static struct mtd_partition __initdata yl9200_nand_partition[] = { - { - .name = "AT91 NAND partition 1, boot", - .offset = 0, - .size = SZ_256K - }, - { - .name = "AT91 NAND partition 2, kernel", - .offset = MTDPART_OFS_NXTBLK, - .size = (2 * SZ_1M) - SZ_256K - }, - { - .name = "AT91 NAND partition 3, filesystem", - .offset = MTDPART_OFS_NXTBLK, - .size = 14 * SZ_1M - }, - { - .name = "AT91 NAND partition 4, storage", - .offset = MTDPART_OFS_NXTBLK, - .size = SZ_16M - }, - { - .name = "AT91 NAND partition 5, ext-fs", - .offset = MTDPART_OFS_NXTBLK, - .size = SZ_32M - } -}; - -static struct atmel_nand_data __initdata yl9200_nand_data = { - .ale = 6, - .cle = 7, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ - .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ - .ecc_mode = NAND_ECC_SOFT, - .parts = yl9200_nand_partition, - .num_parts = ARRAY_SIZE(yl9200_nand_partition), -}; - -/* - * NOR Flash - */ -#define YL9200_FLASH_BASE AT91_CHIPSELECT_0 -#define YL9200_FLASH_SIZE SZ_16M - -static struct mtd_partition yl9200_flash_partitions[] = { - { - .name = "Bootloader", - .offset = 0, - .size = SZ_256K, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "Kernel", - .offset = MTDPART_OFS_NXTBLK, - .size = (2 * SZ_1M) - SZ_256K - }, - { - .name = "Filesystem", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL - } -}; - -static struct physmap_flash_data yl9200_flash_data = { - .width = 2, - .parts = yl9200_flash_partitions, - .nr_parts = ARRAY_SIZE(yl9200_flash_partitions), -}; - -static struct resource yl9200_flash_resources[] = { - { - .start = YL9200_FLASH_BASE, - .end = YL9200_FLASH_BASE + YL9200_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device yl9200_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &yl9200_flash_data, - }, - .resource = yl9200_flash_resources, - .num_resources = ARRAY_SIZE(yl9200_flash_resources), -}; - -/* - * I2C (TWI) - */ -static struct i2c_board_info __initdata yl9200_i2c_devices[] = { - { /* EEPROM */ - I2C_BOARD_INFO("24c128", 0x50), - } -}; - -/* - * GPIO Buttons -*/ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button yl9200_buttons[] = { - { - .gpio = AT91_PIN_PA24, - .code = BTN_2, - .desc = "SW2", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB1, - .code = BTN_3, - .desc = "SW3", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB2, - .code = BTN_4, - .desc = "SW4", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PB6, - .code = BTN_5, - .desc = "SW5", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data yl9200_button_data = { - .buttons = yl9200_buttons, - .nbuttons = ARRAY_SIZE(yl9200_buttons), -}; - -static struct platform_device yl9200_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &yl9200_button_data, - } -}; - -static void __init yl9200_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA24, 1); /* SW2 */ - at91_set_deglitch(AT91_PIN_PA24, 1); - at91_set_gpio_input(AT91_PIN_PB1, 1); /* SW3 */ - at91_set_deglitch(AT91_PIN_PB1, 1); - at91_set_gpio_input(AT91_PIN_PB2, 1); /* SW4 */ - at91_set_deglitch(AT91_PIN_PB2, 1); - at91_set_gpio_input(AT91_PIN_PB6, 1); /* SW5 */ - at91_set_deglitch(AT91_PIN_PB6, 1); - - /* Enable buttons (Sheet 5) */ - at91_set_gpio_output(AT91_PIN_PB7, 1); - - platform_device_register(&yl9200_button_device); -} -#else -static void __init yl9200_add_device_buttons(void) {} -#endif - -/* - * Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - - /* For a 8" touch-screen */ - // .x_plate_ohms = 603, - // .y_plate_ohms = 332, - - /* For a 10.4" touch-screen */ - // .x_plate_ohms = 611, - // .y_plate_ohms = 325, - - .x_plate_ohms = 576, - .y_plate_ohms = 366, - - .pressure_max = 15000, /* generally nonsense on the 7843 */ - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init yl9200_add_device_ts(void) -{ - at91_set_gpio_input(AT91_PIN_PB11, 1); /* Touchscreen interrupt pin */ - at91_set_gpio_input(AT91_PIN_PB10, 1); /* Touchscreen BUSY signal - not used! */ -} -#else -static void __init yl9200_add_device_ts(void) {} -#endif - -/* - * SPI devices - */ -static struct spi_board_info yl9200_spi_devices[] = { -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { /* Touchscreen */ - .modalias = "ads7846", - .chip_select = 0, - .max_speed_hz = 5000 * 26, - .platform_data = &ads_info, - .irq = AT91_PIN_PB11, - }, -#endif - { /* CAN */ - .modalias = "mcp2510", - .chip_select = 1, - .max_speed_hz = 25000 * 26, - .irq = AT91_PIN_PC0, - } -}; - -/* - * LCD / VGA - * - * EPSON S1D13806 FB (discontinued chip) - * EPSON S1D13506 FB - */ -#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE) -#include <video/s1d13xxxfb.h> - - -static void yl9200_init_video(void) -{ - /* NWAIT Signal */ - at91_set_A_periph(AT91_PIN_PC6, 0); - - /* Initialization of the Static Memory Controller for Chip Select 2 */ - at91_ramc_write(0, AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ - | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */ - | AT91_SMC_TDF_(0x100) /* float time */ - ); -} - -static struct s1d13xxxfb_regval yl9200_s1dfb_initregs[] = -{ - {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/ - {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/ - {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/ - {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/ - {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/ - {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/ - {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/ - {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/ - {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/ - {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/ - {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/ - {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/ - {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/ - {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/ - {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/ - {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/ - {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/ - {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/ - {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/ - {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/ - {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/ - {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/ - {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/ - {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/ - {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/ - {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/ - {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/ - {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/ - {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/ - {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/ - {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/ - {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/ - {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/ - {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/ - {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/ - {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/ - {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/ - {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/ - {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/ - {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/ - {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/ - {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/ - {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/ - {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */ - {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/ - {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/ - {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/ - {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/ - {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/ - {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/ - {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/ - {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/ - {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/ - {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/ - {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/ - {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/ - {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/ - {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/ - {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/ - {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/ - {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/ - {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/ - {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/ - {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/ - {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/ - {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/ - {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/ - {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/ - {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/ - {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/ - {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/ - {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/ - {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/ - {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/ - {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/ - {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/ - {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/ - {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/ - {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/ - {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/ - {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/ - {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/ - {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/ - {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/ - {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/ - {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/ - {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/ - {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/ - {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/ - {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/ - {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/ - {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/ - {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/ - {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/ - {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/ - {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/ - {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/ - {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/ - {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/ - {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/ - {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/ - {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/ - {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/ - {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/ - {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/ -}; - -static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = { - .initregs = yl9200_s1dfb_initregs, - .initregssize = ARRAY_SIZE(yl9200_s1dfb_initregs), - .platform_init_video = yl9200_init_video, -}; - -#define YL9200_FB_REG_BASE AT91_CHIPSELECT_7 -#define YL9200_FB_VMEM_BASE YL9200_FB_REG_BASE + SZ_2M -#define YL9200_FB_VMEM_SIZE SZ_2M - -static struct resource yl9200_s1dfb_resource[] = { - [0] = { /* video mem */ - .name = "s1d13xxxfb memory", - .start = YL9200_FB_VMEM_BASE, - .end = YL9200_FB_VMEM_BASE + YL9200_FB_VMEM_SIZE -1, - .flags = IORESOURCE_MEM, - }, - [1] = { /* video registers */ - .name = "s1d13xxxfb registers", - .start = YL9200_FB_REG_BASE, - .end = YL9200_FB_REG_BASE + SZ_512 -1, - .flags = IORESOURCE_MEM, - }, -}; - -static u64 s1dfb_dmamask = DMA_BIT_MASK(32); - -static struct platform_device yl9200_s1dfb_device = { - .name = "s1d13806fb", - .id = -1, - .dev = { - .dma_mask = &s1dfb_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &yl9200_s1dfb_pdata, - }, - .resource = yl9200_s1dfb_resource, - .num_resources = ARRAY_SIZE(yl9200_s1dfb_resource), -}; - -void __init yl9200_add_device_video(void) -{ - platform_device_register(&yl9200_s1dfb_device); -} -#else -void __init yl9200_add_device_video(void) {} -#endif - - -static void __init yl9200_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART0 on ttyS2. (Rx & Tx only to JP3) */ - at91_register_uart(AT91RM9200_ID_US0, 2, 0); - - /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */ - at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS); - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&yl9200_eth_data); - /* USB Host */ - at91_add_device_usbh(&yl9200_usbh_data); - /* USB Device */ - at91_add_device_udc(&yl9200_udc_data); - /* I2C */ - at91_add_device_i2c(yl9200_i2c_devices, ARRAY_SIZE(yl9200_i2c_devices)); - /* MMC */ - at91_add_device_mci(0, &yl9200_mci0_data); - /* NAND */ - at91_add_device_nand(&yl9200_nand_data); - /* NOR Flash */ - platform_device_register(&yl9200_flash); -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) - /* SPI */ - at91_add_device_spi(yl9200_spi_devices, ARRAY_SIZE(yl9200_spi_devices)); - /* Touchscreen */ - yl9200_add_device_ts(); -#endif - /* LEDs. */ - at91_gpio_leds(yl9200_leds, ARRAY_SIZE(yl9200_leds)); - /* Push Buttons */ - yl9200_add_device_buttons(); - /* VGA */ - yl9200_add_device_video(); -} - -MACHINE_START(YL9200, "uCdragon YL-9200") - /* Maintainer: S.Birtles */ - .init_time = at91rm9200_timer_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = yl9200_init_early, - .init_irq = at91_init_irq_default, - .init_machine = yl9200_board_init, -MACHINE_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/clock.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/clock.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/clock.c - * - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * - * 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. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/spinlock.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/of_address.h> -#include <linux/clk/at91_pmc.h> - -#include <mach/hardware.h> -#include <mach/cpu.h> - -#include <asm/proc-fns.h> - -#include "clock.h" -#include "generic.h" - -void __iomem *at91_pmc_base; -EXPORT_SYMBOL_GPL(at91_pmc_base); - -/* - * There's a lot more which can be done with clocks, including cpufreq - * integration, slow clock mode support (for system suspend), letting - * PLLB be used at other rates (on boards that don't need USB), etc. - */ - -#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) -#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) -#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) -#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) - - -/* - * Chips have some kind of clocks : group them by functionality - */ -#define cpu_has_utmi() ( cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3()) - -#define cpu_has_1056M_plla() (cpu_is_sama5d3()) - -#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ - || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12()) - -#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) - -#define cpu_has_240M_plla() (cpu_is_at91sam9261() \ - || cpu_is_at91sam9263() \ - || cpu_is_at91sam9rl()) - -#define cpu_has_210M_plla() (cpu_is_at91sam9260()) - -#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3())) - -#define cpu_has_upll() (cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3()) - -/* USB host HS & FS */ -#define cpu_has_uhp() (!cpu_is_at91sam9rl()) - -/* USB device FS only */ -#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3())) - -#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) - -#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) - -#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) - -static LIST_HEAD(clocks); -static DEFINE_SPINLOCK(clk_lock); - -static u32 at91_pllb_usb_init; - -/* - * Four primary clock sources: two crystal oscillators (32K, main), and - * two PLLs. PLLA usually runs the master clock; and PLLB must run at - * 48 MHz (unless no USB function clocks are needed). The main clock and - * both PLLs are turned off to run in "slow clock mode" (system suspend). - */ -static struct clk clk32k = { - .name = "clk32k", - .rate_hz = AT91_SLOW_CLOCK, - .users = 1, /* always on */ - .id = 0, - .type = CLK_TYPE_PRIMARY, -}; -static struct clk main_clk = { - .name = "main", - .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ - .id = 1, - .type = CLK_TYPE_PRIMARY, -}; -static struct clk plla = { - .name = "plla", - .parent = &main_clk, - .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ - .id = 2, - .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, -}; - -static void pllb_mode(struct clk *clk, int is_on) -{ - u32 value; - - if (is_on) { - is_on = AT91_PMC_LOCKB; - value = at91_pllb_usb_init; - } else - value = 0; - - // REVISIT: Add work-around for AT91RM9200 Errata #26 ? - at91_pmc_write(AT91_CKGR_PLLBR, value); - - do { - cpu_relax(); - } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); -} - -static struct clk pllb = { - .name = "pllb", - .parent = &main_clk, - .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ - .mode = pllb_mode, - .id = 3, - .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, -}; - -static void pmc_sys_mode(struct clk *clk, int is_on) -{ - if (is_on) - at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask); - else - at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask); -} - -static void pmc_uckr_mode(struct clk *clk, int is_on) -{ - unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); - - if (is_on) { - is_on = AT91_PMC_LOCKU; - at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); - } else - at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); - - do { - cpu_relax(); - } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); -} - -/* USB function clocks (PLLB must be 48 MHz) */ -static struct clk udpck = { - .name = "udpck", - .parent = &pllb, - .mode = pmc_sys_mode, -}; -struct clk utmi_clk = { - .name = "utmi_clk", - .parent = &main_clk, - .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */ - .mode = pmc_uckr_mode, - .type = CLK_TYPE_PLL, -}; -static struct clk uhpck = { - .name = "uhpck", - /*.parent = ... we choose parent at runtime */ - .mode = pmc_sys_mode, -}; - - -/* - * The master clock is divided from the CPU clock (by 1-4). It's used for - * memory, interfaces to on-chip peripherals, the AIC, and sometimes more - * (e.g baud rate generation). It's sourced from one of the primary clocks. - */ -struct clk mck = { - .name = "mck", - .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ -}; - -static void pmc_periph_mode(struct clk *clk, int is_on) -{ - u32 regval = 0; - - /* - * With sama5d3 devices, we are managing clock division so we have to - * use the Peripheral Control Register introduced from at91sam9x5 - * devices. - */ - if (cpu_is_sama5d3()) { - regval |= AT91_PMC_PCR_CMD; /* write command */ - regval |= clk->pid & AT91_PMC_PCR_PID; /* peripheral selection */ - regval |= AT91_PMC_PCR_DIV(clk->div); - if (is_on) - regval |= AT91_PMC_PCR_EN; /* enable clock */ - at91_pmc_write(AT91_PMC_PCR, regval); - } else { - if (is_on) - at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); - else - at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); - } -} - -static struct clk __init *at91_css_to_clk(unsigned long css) -{ - switch (css) { - case AT91_PMC_CSS_SLOW: - return &clk32k; - case AT91_PMC_CSS_MAIN: - return &main_clk; - case AT91_PMC_CSS_PLLA: - return &plla; - case AT91_PMC_CSS_PLLB: - if (cpu_has_upll()) - /* CSS_PLLB == CSS_UPLL */ - return &utmi_clk; - else if (cpu_has_pllb()) - return &pllb; - break; - /* alternate PMC: can use master clock */ - case AT91_PMC_CSS_MASTER: - return &mck; - } - - return NULL; -} - -static int pmc_prescaler_divider(u32 reg) -{ - if (cpu_has_alt_prescaler()) { - return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET); - } else { - return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET); - } -} - -static void __clk_enable(struct clk *clk) -{ - if (clk->parent) - __clk_enable(clk->parent); - if (clk->users++ == 0 && clk->mode) - clk->mode(clk, 1); -} - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - - spin_lock_irqsave(&clk_lock, flags); - __clk_enable(clk); - spin_unlock_irqrestore(&clk_lock, flags); - return 0; -} -EXPORT_SYMBOL(clk_enable); - -static void __clk_disable(struct clk *clk) -{ - BUG_ON(clk->users == 0); - if (--clk->users == 0 && clk->mode) - clk->mode(clk, 0); - if (clk->parent) - __clk_disable(clk->parent); -} - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - spin_lock_irqsave(&clk_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clk_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - unsigned long flags; - unsigned long rate; - - spin_lock_irqsave(&clk_lock, flags); - for (;;) { - rate = clk->rate_hz; - if (rate || !clk->parent) - break; - clk = clk->parent; - } - spin_unlock_irqrestore(&clk_lock, flags); - return rate; -} -EXPORT_SYMBOL(clk_get_rate); - -/*------------------------------------------------------------------------*/ - -/* - * For now, only the programmable clocks support reparenting (MCK could - * do this too, with care) or rate changing (the PLLs could do this too, - * ditto MCK but that's more for cpufreq). Drivers may reparent to get - * a better rate match; we don't. - */ - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long flags; - unsigned prescale; - unsigned long actual; - unsigned long prev = ULONG_MAX; - - if (!clk_is_programmable(clk)) - return -EINVAL; - spin_lock_irqsave(&clk_lock, flags); - - actual = clk->parent->rate_hz; - for (prescale = 0; prescale < 7; prescale++) { - if (actual > rate) - prev = actual; - - if (actual && actual <= rate) { - if ((prev - rate) < (rate - actual)) { - actual = prev; - prescale--; - } - break; - } - actual >>= 1; - } - - spin_unlock_irqrestore(&clk_lock, flags); - return (prescale < 7) ? actual : -ENOENT; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long flags; - unsigned prescale; - unsigned long prescale_offset, css_mask; - unsigned long actual; - - if (!clk_is_programmable(clk)) - return -EINVAL; - if (clk->users) - return -EBUSY; - - if (cpu_has_alt_prescaler()) { - prescale_offset = PMC_ALT_PRES_OFFSET; - css_mask = AT91_PMC_ALT_PCKR_CSS; - } else { - prescale_offset = PMC_PRES_OFFSET; - css_mask = AT91_PMC_CSS; - } - - spin_lock_irqsave(&clk_lock, flags); - - actual = clk->parent->rate_hz; - for (prescale = 0; prescale < 7; prescale++) { - if (actual && actual <= rate) { - u32 pckr; - - pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); - pckr &= css_mask; /* keep clock selection */ - pckr |= prescale << prescale_offset; - at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr); - clk->rate_hz = actual; - break; - } - actual >>= 1; - } - - spin_unlock_irqrestore(&clk_lock, flags); - return (prescale < 7) ? actual : -ENOENT; -} -EXPORT_SYMBOL(clk_set_rate); - -struct clk *clk_get_parent(struct clk *clk) -{ - return clk->parent; -} -EXPORT_SYMBOL(clk_get_parent); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned long flags; - - if (clk->users) - return -EBUSY; - if (!clk_is_primary(parent) || !clk_is_programmable(clk)) - return -EINVAL; - - if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB) - return -EINVAL; - - spin_lock_irqsave(&clk_lock, flags); - - clk->rate_hz = parent->rate_hz; - clk->parent = parent; - at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id); - - spin_unlock_irqrestore(&clk_lock, flags); - return 0; -} -EXPORT_SYMBOL(clk_set_parent); - -/* establish PCK0..PCKN parentage and rate */ -static void __init init_programmable_clock(struct clk *clk) -{ - struct clk *parent; - u32 pckr; - unsigned int css_mask; - - if (cpu_has_alt_prescaler()) - css_mask = AT91_PMC_ALT_PCKR_CSS; - else - css_mask = AT91_PMC_CSS; - - pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); - parent = at91_css_to_clk(pckr & css_mask); - clk->parent = parent; - clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr); -} - -/*------------------------------------------------------------------------*/ - -#ifdef CONFIG_DEBUG_FS - -static int at91_clk_show(struct seq_file *s, void *unused) -{ - u32 scsr, pcsr, pcsr1 = 0, uckr = 0, sr; - struct clk *clk; - - scsr = at91_pmc_read(AT91_PMC_SCSR); - pcsr = at91_pmc_read(AT91_PMC_PCSR); - if (cpu_is_sama5d3()) - pcsr1 = at91_pmc_read(AT91_PMC_PCSR1); - sr = at91_pmc_read(AT91_PMC_SR); - seq_printf(s, "SCSR = %8x\n", scsr); - seq_printf(s, "PCSR = %8x\n", pcsr); - if (cpu_is_sama5d3()) - seq_printf(s, "PCSR1 = %8x\n", pcsr1); - seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); - seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); - seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); - if (cpu_has_pllb()) - seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR)); - if (cpu_has_utmi()) { - uckr = at91_pmc_read(AT91_CKGR_UCKR); - seq_printf(s, "UCKR = %8x\n", uckr); - } - seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR)); - if (cpu_has_upll() || cpu_is_at91sam9n12()) - seq_printf(s, "USB = %8x\n", at91_pmc_read(AT91_PMC_USB)); - seq_printf(s, "SR = %8x\n", sr); - - seq_printf(s, "\n"); - - list_for_each_entry(clk, &clocks, node) { - char *state; - - if (clk->mode == pmc_sys_mode) { - state = (scsr & clk->pmc_mask) ? "on" : "off"; - } else if (clk->mode == pmc_periph_mode) { - if (cpu_is_sama5d3()) { - u32 pmc_mask = 1 << (clk->pid % 32); - - if (clk->pid > 31) - state = (pcsr1 & pmc_mask) ? "on" : "off"; - else - state = (pcsr & pmc_mask) ? "on" : "off"; - } else { - state = (pcsr & clk->pmc_mask) ? "on" : "off"; - } - } else if (clk->mode == pmc_uckr_mode) { - state = (uckr & clk->pmc_mask) ? "on" : "off"; - } else if (clk->pmc_mask) { - state = (sr & clk->pmc_mask) ? "on" : "off"; - } else if (clk == &clk32k || clk == &main_clk) { - state = "on"; - } else { - state = ""; - } - - seq_printf(s, "%-10s users=%2d %-3s %9lu Hz %s\n", - clk->name, clk->users, state, clk_get_rate(clk), - clk->parent ? clk->parent->name : ""); - } - return 0; -} - -static int at91_clk_open(struct inode *inode, struct file *file) -{ - return single_open(file, at91_clk_show, NULL); -} - -static const struct file_operations at91_clk_operations = { - .open = at91_clk_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init at91_clk_debugfs_init(void) -{ - /* /sys/kernel/debug/at91_clk */ - (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations); - - return 0; -} -postcore_initcall(at91_clk_debugfs_init); - -#endif - -/*------------------------------------------------------------------------*/ - -/* Register a new clock */ -static void __init at91_clk_add(struct clk *clk) -{ - list_add_tail(&clk->node, &clocks); - - clk->cl.con_id = clk->name; - clk->cl.clk = clk; - clkdev_add(&clk->cl); -} - -int __init clk_register(struct clk *clk) -{ - if (clk_is_peripheral(clk)) { - if (!clk->parent) - clk->parent = &mck; - if (cpu_is_sama5d3()) - clk->rate_hz = DIV_ROUND_UP(clk->parent->rate_hz, - 1 << clk->div); - clk->mode = pmc_periph_mode; - } - else if (clk_is_sys(clk)) { - clk->parent = &mck; - clk->mode = pmc_sys_mode; - } - else if (clk_is_programmable(clk)) { - clk->mode = pmc_sys_mode; - init_programmable_clock(clk); - } - - at91_clk_add(clk); - - return 0; -} - -/*------------------------------------------------------------------------*/ - -static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) -{ - unsigned mul, div; - - div = reg & 0xff; - if (cpu_is_sama5d3()) - mul = AT91_PMC3_MUL_GET(reg); - else - mul = AT91_PMC_MUL_GET(reg); - - if (div && mul) { - freq /= div; - freq *= mul + 1; - } else - freq = 0; - - return freq; -} - -static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) -{ - if (pll == &pllb && (reg & AT91_PMC_USB96M)) - return freq / 2; - else if (pll == &utmi_clk || cpu_is_at91sam9n12()) - return freq / (1 + ((reg & AT91_PMC_OHCIUSBDIV) >> 8)); - else - return freq; -} - -static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) -{ - unsigned i, div = 0, mul = 0, diff = 1 << 30; - unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; - - /* PLL output max 240 MHz (or 180 MHz per errata) */ - if (out_freq > 240000000) - goto fail; - - for (i = 1; i < 256; i++) { - int diff1; - unsigned input, mul1; - - /* - * PLL input between 1MHz and 32MHz per spec, but lower - * frequences seem necessary in some cases so allow 100K. - * Warning: some newer products need 2MHz min. - */ - input = main_freq / i; - if (cpu_is_at91sam9g20() && input < 2000000) - continue; - if (input < 100000) - continue; - if (input > 32000000) - continue; - - mul1 = out_freq / input; - if (cpu_is_at91sam9g20() && mul > 63) - continue; - if (mul1 > 2048) - continue; - if (mul1 < 2) - goto fail; - - diff1 = out_freq - input * mul1; - if (diff1 < 0) - diff1 = -diff1; - if (diff > diff1) { - diff = diff1; - div = i; - mul = mul1; - if (diff == 0) - break; - } - } - if (i == 256 && diff > (out_freq >> 5)) - goto fail; - return ret | ((mul - 1) << 16) | div; -fail: - return 0; -} - -static struct clk *const standard_pmc_clocks[] __initconst = { - /* four primary clocks */ - &clk32k, - &main_clk, - &plla, - - /* MCK */ - &mck -}; - -/* PLLB generated USB full speed clock init */ -static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) -{ - unsigned int reg; - - /* - * USB clock init: choose 48 MHz PLLB value, - * disable 48MHz clock during usb peripheral suspend. - * - * REVISIT: assumes MCK doesn't derive from PLLB! - */ - uhpck.parent = &pllb; - - reg = at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2); - pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); - if (cpu_is_at91rm9200()) { - reg = at91_pllb_usb_init |= AT91_PMC_USB96M; - uhpck.pmc_mask = AT91RM9200_PMC_UHP; - udpck.pmc_mask = AT91RM9200_PMC_UDP; - at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || - cpu_is_at91sam9263() || cpu_is_at91sam9g20() || - cpu_is_at91sam9g10()) { - reg = at91_pllb_usb_init |= AT91_PMC_USB96M; - uhpck.pmc_mask = AT91SAM926x_PMC_UHP; - udpck.pmc_mask = AT91SAM926x_PMC_UDP; - } else if (cpu_is_at91sam9n12()) { - /* Divider for USB clock is in USB clock register for 9n12 */ - reg = AT91_PMC_USBS_PLLB; - - /* For PLLB output 96M, set usb divider 2 (USBDIV + 1) */ - reg |= AT91_PMC_OHCIUSBDIV_2; - at91_pmc_write(AT91_PMC_USB, reg); - - /* Still setup masks */ - uhpck.pmc_mask = AT91SAM926x_PMC_UHP; - udpck.pmc_mask = AT91SAM926x_PMC_UDP; - } - at91_pmc_write(AT91_CKGR_PLLBR, 0); - - udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, reg); - uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, reg); -} - -/* UPLL generated USB full speed clock init */ -static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) -{ - /* - * USB clock init: choose 480 MHz from UPLL, - */ - unsigned int usbr = AT91_PMC_USBS_UPLL; - - /* Setup divider by 10 to reach 48 MHz */ - usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV; - - at91_pmc_write(AT91_PMC_USB, usbr); - - /* Now set uhpck values */ - uhpck.parent = &utmi_clk; - uhpck.pmc_mask = AT91SAM926x_PMC_UHP; - uhpck.rate_hz = at91_usb_rate(&utmi_clk, utmi_clk.rate_hz, usbr); -} - -static int __init at91_pmc_init(unsigned long main_clock) -{ - unsigned tmp, freq, mckr; - int i; - int pll_overclock = false; - - /* - * When the bootloader initialized the main oscillator correctly, - * there's no problem using the cycle counter. But if it didn't, - * or when using oscillator bypass mode, we must be told the speed - * of the main clock. - */ - if (!main_clock) { - do { - tmp = at91_pmc_read(AT91_CKGR_MCFR); - } while (!(tmp & AT91_PMC_MAINRDY)); - main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); - } - main_clk.rate_hz = main_clock; - - /* report if PLLA is more than mildly overclocked */ - plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); - if (cpu_has_1056M_plla()) { - if (plla.rate_hz > 1056000000) - pll_overclock = true; - } else if (cpu_has_800M_plla()) { - if (plla.rate_hz > 800000000) - pll_overclock = true; - } else if (cpu_has_300M_plla()) { - if (plla.rate_hz > 300000000) - pll_overclock = true; - } else if (cpu_has_240M_plla()) { - if (plla.rate_hz > 240000000) - pll_overclock = true; - } else if (cpu_has_210M_plla()) { - if (plla.rate_hz > 210000000) - pll_overclock = true; - } else { - if (plla.rate_hz > 209000000) - pll_overclock = true; - } - if (pll_overclock) - pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); - - if (cpu_has_plladiv2()) { - mckr = at91_pmc_read(AT91_PMC_MCKR); - plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ - } - - if (!cpu_has_pllb() && cpu_has_upll()) { - /* setup UTMI clock as the fourth primary clock - * (instead of pllb) */ - utmi_clk.type |= CLK_TYPE_PRIMARY; - utmi_clk.id = 3; - } - - - /* - * USB HS clock init - */ - if (cpu_has_utmi()) { - /* - * multiplier is hard-wired to 40 - * (obtain the USB High Speed 480 MHz when input is 12 MHz) - */ - utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; - - /* UTMI bias and PLL are managed at the same time */ - if (cpu_has_upll()) - utmi_clk.pmc_mask |= AT91_PMC_BIASEN; - } - - /* - * USB FS clock init - */ - if (cpu_has_pllb()) - at91_pllb_usbfs_clock_init(main_clock); - if (cpu_has_upll()) - /* assumes that we choose UPLL for USB and not PLLA */ - at91_upll_usbfs_clock_init(main_clock); - - /* - * MCK and CPU derive from one of those primary clocks. - * For now, assume this parentage won't change. - */ - mckr = at91_pmc_read(AT91_PMC_MCKR); - mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); - freq = mck.parent->rate_hz; - freq /= pmc_prescaler_divider(mckr); /* prescale */ - if (cpu_is_at91rm9200()) { - mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - } else if (cpu_is_at91sam9g20()) { - mck.rate_hz = (mckr & AT91_PMC_MDIV) ? - freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ - if (mckr & AT91_PMC_PDIV) - freq /= 2; /* processor clock division */ - } else if (cpu_has_mdiv3()) { - mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? - freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - } else { - mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - } - - if (cpu_has_alt_prescaler()) { - /* Programmable clocks can use MCK */ - mck.type |= CLK_TYPE_PRIMARY; - mck.id = 4; - } - - /* Register the PMC's standard clocks */ - for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) - at91_clk_add(standard_pmc_clocks[i]); - - if (cpu_has_pllb()) - at91_clk_add(&pllb); - - if (cpu_has_uhp()) - at91_clk_add(&uhpck); - - if (cpu_has_udpfs()) - at91_clk_add(&udpck); - - if (cpu_has_utmi()) - at91_clk_add(&utmi_clk); - - /* MCK and CPU clock are "always on" */ - clk_enable(&mck); - - printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", - freq / 1000000, (unsigned) mck.rate_hz / 1000000, - (unsigned) main_clock / 1000000, - ((unsigned) main_clock % 1000000) / 1000); - - return 0; -} - -#if defined(CONFIG_OF) -static struct of_device_id pmc_ids[] = { - { .compatible = "atmel,at91rm9200-pmc" }, - { .compatible = "atmel,at91sam9260-pmc" }, - { .compatible = "atmel,at91sam9g45-pmc" }, - { .compatible = "atmel,at91sam9n12-pmc" }, - { .compatible = "atmel,at91sam9x5-pmc" }, - { .compatible = "atmel,sama5d3-pmc" }, - { /*sentinel*/ } -}; - -static struct of_device_id osc_ids[] = { - { .compatible = "atmel,osc" }, - { /*sentinel*/ } -}; - -int __init at91_dt_clock_init(void) -{ - struct device_node *np; - u32 main_clock = 0; - - np = of_find_matching_node(NULL, pmc_ids); - if (!np) - panic("unable to find compatible pmc node in dtb\n"); - - at91_pmc_base = of_iomap(np, 0); - if (!at91_pmc_base) - panic("unable to map pmc cpu registers\n"); - - of_node_put(np); - - /* retrieve the freqency of fixed clocks from device tree */ - np = of_find_matching_node(NULL, osc_ids); - if (np) { - u32 rate; - if (!of_property_read_u32(np, "clock-frequency", &rate)) - main_clock = rate; - } - - of_node_put(np); - - return at91_pmc_init(main_clock); -} -#endif - -int __init at91_clock_init(unsigned long main_clock) -{ - at91_pmc_base = ioremap(AT91_PMC, 256); - if (!at91_pmc_base) - panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC); - - return at91_pmc_init(main_clock); -} - -/* - * Several unused clocks may be active. Turn them off. - */ -static int __init at91_clock_reset(void) -{ - unsigned long pcdr = 0; - unsigned long pcdr1 = 0; - unsigned long scdr = 0; - struct clk *clk; - - list_for_each_entry(clk, &clocks, node) { - if (clk->users > 0) - continue; - - if (clk->mode == pmc_periph_mode) { - if (cpu_is_sama5d3()) { - u32 pmc_mask = 1 << (clk->pid % 32); - - if (clk->pid > 31) - pcdr1 |= pmc_mask; - else - pcdr |= pmc_mask; - } else - pcdr |= clk->pmc_mask; - } - - if (clk->mode == pmc_sys_mode) - scdr |= clk->pmc_mask; - - pr_debug("Clocks: disable unused %s\n", clk->name); - } - - at91_pmc_write(AT91_PMC_SCDR, scdr); - at91_pmc_write(AT91_PMC_PCDR, pcdr); - if (cpu_is_sama5d3()) - at91_pmc_write(AT91_PMC_PCDR1, pcdr1); - - return 0; -} -late_initcall(at91_clock_reset); - -void at91sam9_idle(void) -{ - at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); - cpu_do_idle(); -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/clock.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/clock.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/clock.h - * - * 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 <linux/clkdev.h> - -#define CLK_TYPE_PRIMARY 0x1 -#define CLK_TYPE_PLL 0x2 -#define CLK_TYPE_PROGRAMMABLE 0x4 -#define CLK_TYPE_PERIPHERAL 0x8 -#define CLK_TYPE_SYSTEM 0x10 - - -struct clk { - struct list_head node; - const char *name; /* unique clock name */ - struct clk_lookup cl; - unsigned long rate_hz; - unsigned div; /* parent clock divider */ - struct clk *parent; - unsigned pid; /* peripheral ID */ - u32 pmc_mask; - void (*mode)(struct clk *, int); - unsigned id:3; /* PCK0..4, or 32k/main/a/b */ - unsigned type; /* clock type */ - u16 users; -}; - - -extern int __init clk_register(struct clk *clk); -extern struct clk mck; -extern struct clk utmi_clk; - -#define CLKDEV_CON_ID(_id, _clk) \ - { \ - .con_id = _id, \ - .clk = _clk, \ - } - -#define CLKDEV_CON_DEV_ID(_con_id, _dev_id, _clk) \ - { \ - .con_id = _con_id, \ - .dev_id = _dev_id, \ - .clk = _clk, \ - } Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/generic.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/generic.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/generic.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:14 @ #ifndef _AT91_GENERIC_H #define _AT91_GENERIC_H -#include <linux/clkdev.h> #include <linux/of.h> #include <linux/reboot.h> /* Map io */ extern void __init at91_map_io(void); extern void __init at91_alt_map_io(void); -extern void __init at91_init_sram(int bank, unsigned long base, - unsigned int length); /* Processors */ extern void __init at91rm9200_set_type(int type); -extern void __init at91_initialize(unsigned long main_clock); -extern void __init at91x40_initialize(unsigned long main_clock); extern void __init at91rm9200_dt_initialize(void); extern void __init at91_dt_initialize(void); /* Interrupts */ -extern void __init at91_init_irq_default(void); -extern void __init at91_init_interrupts(unsigned int priority[]); -extern void __init at91x40_init_interrupts(unsigned int priority[]); -extern void __init at91_aic_init(unsigned int priority[], - unsigned int ext_irq_mask); -extern int __init at91_aic_of_init(struct device_node *node, - struct device_node *parent); -extern int __init at91_aic5_of_init(struct device_node *node, - struct device_node *parent); extern void __init at91_sysirq_mask_rtc(u32 rtc_base); extern void __init at91_sysirq_mask_rtt(u32 rtt_base); - /* Devices */ -extern void __init at91_register_devices(void); - /* Timer */ -extern void __init at91_init_time(void); -extern void at91rm9200_ioremap_st(u32 addr); extern void at91rm9200_timer_init(void); -extern void at91sam926x_ioremap_pit(u32 addr); -extern void at91sam926x_pit_init(int irq); -extern void at91x40_timer_init(void); - - /* Clocks */ -#ifdef CONFIG_OLD_CLK_AT91 -extern int __init at91_clock_init(unsigned long main_clock); -extern int __init at91_dt_clock_init(void); -#else -static int inline at91_clock_init(unsigned long main_clock) { return 0; } -static int inline at91_dt_clock_init(void) { return 0; } -#endif -struct device; - - /* Power Management */ -extern void at91_irq_suspend(void); -extern void at91_irq_resume(void); /* idle */ extern void at91sam9_idle(void); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:39 @ extern void at91sam9_idle(void); /* Matrix */ extern void at91_ioremap_matrix(u32 base_addr); -/* Ram Controler */ -extern void at91_ioremap_ramc(int id, u32 addr, u32 size); - /* GPIO */ -#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ -#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ - -struct at91_gpio_bank { - unsigned short id; /* peripheral ID */ - unsigned long regbase; /* offset from system peripheral base */ -}; -extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); -extern void __init at91_gpio_irq_setup(void); -extern int __init at91_gpio_of_irq_setup(struct device_node *node, - struct device_node *parent); - -extern u32 at91_get_extern_irq(void); +#ifdef CONFIG_PM +extern void __init at91rm9200_pm_init(void); +extern void __init at91sam9260_pm_init(void); +extern void __init at91sam9g45_pm_init(void); +extern void __init at91sam9x5_pm_init(void); +extern void __init sam5d3_pm_init(void); +extern void __init sam5d4_pm_init(void); +#else +void __init at91rm9200_pm_init(void) { } +void __init at91sam9260_pm_init(void) { } +void __init at91sam9g45_pm_init(void) { } +void __init at91sam9x5_pm_init(void) { } +void __init sam5d3_pm_init(void) {} +void __init sam5d4_pm_init(void) {} +#endif #endif /* _AT91_GENERIC_H */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/gpio.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/gpio.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/gpio.c - * - * Copyright (C) 2005 HP Labs - * - * 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. - */ - -#include <linux/clk.h> -#include <linux/errno.h> -#include <linux/device.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/io.h> -#include <linux/irqdomain.h> -#include <linux/irqchip/chained_irq.h> -#include <linux/of_address.h> - -#include <mach/hardware.h> -#include <mach/at91_pio.h> - -#include "generic.h" -#include "gpio.h" - -#define MAX_NB_GPIO_PER_BANK 32 - -struct at91_gpio_chip { - struct gpio_chip chip; - struct at91_gpio_chip *next; /* Bank sharing same clock */ - int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ - int pioc_virq; /* PIO bank Linux virtual interrupt */ - int pioc_idx; /* PIO bank index */ - void __iomem *regbase; /* PIO bank virtual address */ - struct clk *clock; /* associated clock */ - struct irq_domain *domain; /* associated irq domain */ -}; - -#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) - -static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset); -static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); -static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); -static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset); -static int at91_gpiolib_get_direction(struct gpio_chip *chip, unsigned offset); -static int at91_gpiolib_direction_output(struct gpio_chip *chip, - unsigned offset, int val); -static int at91_gpiolib_direction_input(struct gpio_chip *chip, - unsigned offset); -static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); - -#define AT91_GPIO_CHIP(name) \ - { \ - .chip = { \ - .label = name, \ - .request = at91_gpiolib_request, \ - .get_direction = at91_gpiolib_get_direction, \ - .direction_input = at91_gpiolib_direction_input, \ - .direction_output = at91_gpiolib_direction_output, \ - .get = at91_gpiolib_get, \ - .set = at91_gpiolib_set, \ - .dbg_show = at91_gpiolib_dbg_show, \ - .to_irq = at91_gpiolib_to_irq, \ - .ngpio = MAX_NB_GPIO_PER_BANK, \ - }, \ - } - -static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA"), - AT91_GPIO_CHIP("pioB"), - AT91_GPIO_CHIP("pioC"), - AT91_GPIO_CHIP("pioD"), - AT91_GPIO_CHIP("pioE"), -}; - -static int gpio_banks; -static unsigned long at91_gpio_caps; - -/* All PIO controllers support PIO3 features */ -#define AT91_GPIO_CAP_PIO3 (1 << 0) - -#define has_pio3() (at91_gpio_caps & AT91_GPIO_CAP_PIO3) - -/*--------------------------------------------------------------------------*/ - -static inline void __iomem *pin_to_controller(unsigned pin) -{ - pin /= MAX_NB_GPIO_PER_BANK; - if (likely(pin < gpio_banks)) - return gpio_chip[pin].regbase; - - return NULL; -} - -static inline unsigned pin_to_mask(unsigned pin) -{ - return 1 << (pin % MAX_NB_GPIO_PER_BANK); -} - - -static char peripheral_function(void __iomem *pio, unsigned mask) -{ - char ret = 'X'; - u8 select; - - if (pio) { - if (has_pio3()) { - select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); - select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); - ret = 'A' + select; - } else { - ret = __raw_readl(pio + PIO_ABSR) & mask ? - 'B' : 'A'; - } - } - - return ret; -} - -/*--------------------------------------------------------------------------*/ - -/* Not all hardware capabilities are exposed through these calls; they - * only encapsulate the most common features and modes. (So if you - * want to change signals in groups, do it directly.) - * - * Bootloaders will usually handle some of the pin multiplexing setup. - * The intent is certainly that by the time Linux is fully booted, all - * pins should have been fully initialized. These setup calls should - * only be used by board setup routines, or possibly in driver probe(). - * - * For bootloaders doing all that setup, these calls could be inlined - * as NOPs so Linux won't duplicate any setup code - */ - - -/* - * mux the pin to the "GPIO" peripheral role. - */ -int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_PER); - return 0; -} -EXPORT_SYMBOL(at91_set_GPIO_periph); - - -/* - * mux the pin to the "A" internal peripheral role. - */ -int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - if (has_pio3()) { - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, - pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); - } else { - __raw_writel(mask, pio + PIO_ASR); - } - __raw_writel(mask, pio + PIO_PDR); - return 0; -} -EXPORT_SYMBOL(at91_set_A_periph); - - -/* - * mux the pin to the "B" internal peripheral role. - */ -int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - if (has_pio3()) { - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, - pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); - } else { - __raw_writel(mask, pio + PIO_BSR); - } - __raw_writel(mask, pio + PIO_PDR); - return 0; -} -EXPORT_SYMBOL(at91_set_B_periph); - - -/* - * mux the pin to the "C" internal peripheral role. - */ -int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio || !has_pio3()) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); - __raw_writel(mask, pio + PIO_PDR); - return 0; -} -EXPORT_SYMBOL(at91_set_C_periph); - - -/* - * mux the pin to the "D" internal peripheral role. - */ -int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio || !has_pio3()) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); - __raw_writel(mask, pio + PIO_PDR); - return 0; -} -EXPORT_SYMBOL(at91_set_D_periph); - - -/* - * mux the pin to the gpio controller (instead of "A", "B", "C" - * or "D" peripheral), and configure it for an input. - */ -int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_ODR); - __raw_writel(mask, pio + PIO_PER); - return 0; -} -EXPORT_SYMBOL(at91_set_gpio_input); - - -/* - * mux the pin to the gpio controller (instead of "A", "B", "C" - * or "D" peripheral), and configure it for an output. - */ -int __init_or_module at91_set_gpio_output(unsigned pin, int value) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - __raw_writel(mask, pio + PIO_IDR); - __raw_writel(mask, pio + PIO_PUDR); - __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); - __raw_writel(mask, pio + PIO_OER); - __raw_writel(mask, pio + PIO_PER); - return 0; -} -EXPORT_SYMBOL(at91_set_gpio_output); - - -/* - * enable/disable the glitch filter; mostly used with IRQ handling. - */ -int __init_or_module at91_set_deglitch(unsigned pin, int is_on) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - if (has_pio3() && is_on) - __raw_writel(mask, pio + PIO_IFSCDR); - __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); - return 0; -} -EXPORT_SYMBOL(at91_set_deglitch); - -/* - * enable/disable the debounce filter; - */ -int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio || !has_pio3()) - return -EINVAL; - - if (is_on) { - __raw_writel(mask, pio + PIO_IFSCER); - __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); - __raw_writel(mask, pio + PIO_IFER); - } else { - __raw_writel(mask, pio + PIO_IFDR); - } - return 0; -} -EXPORT_SYMBOL(at91_set_debounce); - -/* - * enable/disable the multi-driver; This is only valid for output and - * allows the output pin to run as an open collector output. - */ -int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - - __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR)); - return 0; -} -EXPORT_SYMBOL(at91_set_multi_drive); - -/* - * enable/disable the pull-down. - * If pull-up already enabled while calling the function, we disable it. - */ -int __init_or_module at91_set_pulldown(unsigned pin, int is_on) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio || !has_pio3()) - return -EINVAL; - - /* Disable pull-up anyway */ - __raw_writel(mask, pio + PIO_PUDR); - __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); - return 0; -} -EXPORT_SYMBOL(at91_set_pulldown); - -/* - * disable Schmitt trigger - */ -int __init_or_module at91_disable_schmitt_trig(unsigned pin) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio || !has_pio3()) - return -EINVAL; - - __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); - return 0; -} -EXPORT_SYMBOL(at91_disable_schmitt_trig); - -/* - * assuming the pin is muxed as a gpio output, set its value. - */ -int at91_set_gpio_value(unsigned pin, int value) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (!pio) - return -EINVAL; - __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); - return 0; -} -EXPORT_SYMBOL(at91_set_gpio_value); - - -/* - * read the pin's value (works even if it's not muxed as a gpio). - */ -int at91_get_gpio_value(unsigned pin) -{ - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - u32 pdsr; - - if (!pio) - return -EINVAL; - pdsr = __raw_readl(pio + PIO_PDSR); - return (pdsr & mask) != 0; -} -EXPORT_SYMBOL(at91_get_gpio_value); - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM - -static u32 wakeups[MAX_GPIO_BANKS]; -static u32 backups[MAX_GPIO_BANKS]; - -static int gpio_irq_set_wake(struct irq_data *d, unsigned state) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - unsigned mask = 1 << d->hwirq; - unsigned bank = at91_gpio->pioc_idx; - - if (unlikely(bank >= MAX_GPIO_BANKS)) - return -EINVAL; - - if (state) - wakeups[bank] |= mask; - else - wakeups[bank] &= ~mask; - - irq_set_irq_wake(at91_gpio->pioc_virq, state); - - return 0; -} - -void at91_gpio_suspend(void) -{ - int i; - - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio = gpio_chip[i].regbase; - - backups[i] = __raw_readl(pio + PIO_IMR); - __raw_writel(backups[i], pio + PIO_IDR); - __raw_writel(wakeups[i], pio + PIO_IER); - - if (!wakeups[i]) { - clk_unprepare(gpio_chip[i].clock); - clk_disable(gpio_chip[i].clock); - } else { -#ifdef CONFIG_PM_DEBUG - printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); -#endif - } - } -} - -void at91_gpio_resume(void) -{ - int i; - - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio = gpio_chip[i].regbase; - - if (!wakeups[i]) { - if (clk_prepare(gpio_chip[i].clock) == 0) - clk_enable(gpio_chip[i].clock); - } - - __raw_writel(wakeups[i], pio + PIO_IDR); - __raw_writel(backups[i], pio + PIO_IER); - } -} - -#else -#define gpio_irq_set_wake NULL -#endif - - -/* Several AIC controller irqs are dispatched through this GPIO handler. - * To use any AT91_PIN_* as an externally triggered IRQ, first call - * at91_set_gpio_input() then maybe enable its glitch filter. - * Then just request_irq() with the pin ID; it works like any ARM IRQ - * handler. - * First implementation always triggers on rising and falling edges - * whereas the newer PIO3 can be additionally configured to trigger on - * level, edge with any polarity. - * - * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after - * configuring them with at91_set_a_periph() or at91_set_b_periph(). - * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. - */ - -static void gpio_irq_mask(struct irq_data *d) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - if (pio) - __raw_writel(mask, pio + PIO_IDR); -} - -static void gpio_irq_unmask(struct irq_data *d) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - if (pio) - __raw_writel(mask, pio + PIO_IER); -} - -static int gpio_irq_type(struct irq_data *d, unsigned type) -{ - switch (type) { - case IRQ_TYPE_NONE: - case IRQ_TYPE_EDGE_BOTH: - return 0; - default: - return -EINVAL; - } -} - -/* Alternate irq type for PIO3 support */ -static int alt_gpio_irq_type(struct irq_data *d, unsigned type) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - __raw_writel(mask, pio + PIO_ESR); - __raw_writel(mask, pio + PIO_REHLSR); - break; - case IRQ_TYPE_EDGE_FALLING: - __raw_writel(mask, pio + PIO_ESR); - __raw_writel(mask, pio + PIO_FELLSR); - break; - case IRQ_TYPE_LEVEL_LOW: - __raw_writel(mask, pio + PIO_LSR); - __raw_writel(mask, pio + PIO_FELLSR); - break; - case IRQ_TYPE_LEVEL_HIGH: - __raw_writel(mask, pio + PIO_LSR); - __raw_writel(mask, pio + PIO_REHLSR); - break; - case IRQ_TYPE_EDGE_BOTH: - /* - * disable additional interrupt modes: - * fall back to default behavior - */ - __raw_writel(mask, pio + PIO_AIMDR); - return 0; - case IRQ_TYPE_NONE: - default: - pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); - return -EINVAL; - } - - /* enable additional interrupt modes */ - __raw_writel(mask, pio + PIO_AIMER); - - return 0; -} - -static struct irq_chip gpio_irqchip = { - .name = "GPIO", - .irq_disable = gpio_irq_mask, - .irq_mask = gpio_irq_mask, - .irq_unmask = gpio_irq_unmask, - /* .irq_set_type is set dynamically */ - .irq_set_wake = gpio_irq_set_wake, -}; - -static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *idata = irq_desc_get_irq_data(desc); - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); - void __iomem *pio = at91_gpio->regbase; - unsigned long isr; - int n; - - chained_irq_enter(chip, desc); - for (;;) { - /* Reading ISR acks pending (edge triggered) GPIO interrupts. - * When there none are pending, we're finished unless we need - * to process multiple banks (like ID_PIOCDE on sam9263). - */ - isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); - if (!isr) { - if (!at91_gpio->next) - break; - at91_gpio = at91_gpio->next; - pio = at91_gpio->regbase; - continue; - } - - n = find_first_bit(&isr, BITS_PER_LONG); - while (n < BITS_PER_LONG) { - generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); - n = find_next_bit(&isr, BITS_PER_LONG, n + 1); - } - } - chained_irq_exit(chip, desc); - /* now it may re-trigger */ -} - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_DEBUG_FS - -static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask) -{ - char *trigger = NULL; - char *polarity = NULL; - - if (__raw_readl(pio + PIO_IMR) & mask) { - if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) { - trigger = "edge"; - polarity = "both"; - } else { - if (__raw_readl(pio + PIO_ELSR) & mask) { - trigger = "level"; - polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? - "high" : "low"; - } else { - trigger = "edge"; - polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? - "rising" : "falling"; - } - } - seq_printf(s, "IRQ:%s-%s\t", trigger, polarity); - } else { - seq_printf(s, "GPIO:%s\t\t", - __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); - } -} - -static int at91_gpio_show(struct seq_file *s, void *unused) -{ - int bank, j; - - /* print heading */ - seq_printf(s, "Pin\t"); - for (bank = 0; bank < gpio_banks; bank++) { - seq_printf(s, "PIO%c\t\t", 'A' + bank); - }; - seq_printf(s, "\n\n"); - - /* print pin status */ - for (j = 0; j < 32; j++) { - seq_printf(s, "%i:\t", j); - - for (bank = 0; bank < gpio_banks; bank++) { - unsigned pin = (32 * bank) + j; - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - - if (__raw_readl(pio + PIO_PSR) & mask) - gpio_printf(s, pio, mask); - else - seq_printf(s, "%c\t\t", - peripheral_function(pio, mask)); - } - - seq_printf(s, "\n"); - } - - return 0; -} - -static int at91_gpio_open(struct inode *inode, struct file *file) -{ - return single_open(file, at91_gpio_show, NULL); -} - -static const struct file_operations at91_gpio_operations = { - .open = at91_gpio_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init at91_gpio_debugfs_init(void) -{ - /* /sys/kernel/debug/at91_gpio */ - (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations); - return 0; -} -postcore_initcall(at91_gpio_debugfs_init); - -#endif - -/*--------------------------------------------------------------------------*/ - -/* - * This lock class tells lockdep that GPIO irqs are in a different - * category than their parents, so it won't report false recursion. - */ -static struct lock_class_key gpio_lock_class; - -/* - * irqdomain initialization: pile up irqdomains on top of AIC range - */ -static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) -{ - int irq_base; - - irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); - if (irq_base < 0) - panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", - at91_gpio->pioc_idx, irq_base); - at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio, - irq_base, 0, - &irq_domain_simple_ops, NULL); - if (!at91_gpio->domain) - panic("at91_gpio.%d: couldn't allocate irq domain.\n", - at91_gpio->pioc_idx); -} - -/* - * Called from the processor-specific init to enable GPIO interrupt support. - */ -void __init at91_gpio_irq_setup(void) -{ - unsigned pioc; - int gpio_irqnbr = 0; - struct at91_gpio_chip *this, *prev; - - /* Setup proper .irq_set_type function */ - if (has_pio3()) - gpio_irqchip.irq_set_type = alt_gpio_irq_type; - else - gpio_irqchip.irq_set_type = gpio_irq_type; - - for (pioc = 0, this = gpio_chip, prev = NULL; - pioc++ < gpio_banks; - prev = this, this++) { - int offset; - - __raw_writel(~0, this->regbase + PIO_IDR); - - /* setup irq domain for this GPIO controller */ - at91_gpio_irqdomain(this); - - for (offset = 0; offset < this->chip.ngpio; offset++) { - unsigned int virq = irq_find_mapping(this->domain, offset); - irq_set_lockdep_class(virq, &gpio_lock_class); - - /* - * Can use the "simple" and not "edge" handler since it's - * shorter, and the AIC handles interrupts sanely. - */ - irq_set_chip_and_handler(virq, &gpio_irqchip, - handle_simple_irq); - set_irq_flags(virq, IRQF_VALID); - irq_set_chip_data(virq, this); - - gpio_irqnbr++; - } - - /* The toplevel handler handles one bank of GPIOs, except - * on some SoC it can handles up to three... - * We only set up the handler for the first of the list. - */ - if (prev && prev->next == this) - continue; - - this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq); - irq_set_chip_data(this->pioc_virq, this); - irq_set_chained_handler(this->pioc_virq, gpio_irq_handler); - } - pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); -} - -/* gpiolib support */ -static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - __raw_writel(mask, pio + PIO_PER); - return 0; -} - -static int at91_gpiolib_get_direction(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - u32 osr; - - osr = __raw_readl(pio + PIO_OSR); - return !(osr & mask); -} - -static int at91_gpiolib_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - __raw_writel(mask, pio + PIO_ODR); - return 0; -} - -static int at91_gpiolib_direction_output(struct gpio_chip *chip, - unsigned offset, int val) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); - __raw_writel(mask, pio + PIO_OER); - return 0; -} - -static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - u32 pdsr; - - pdsr = __raw_readl(pio + PIO_PDSR); - return (pdsr & mask) != 0; -} - -static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); -} - -static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) -{ - int i; - - for (i = 0; i < chip->ngpio; i++) { - unsigned pin = chip->base + i; - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); - const char *gpio_label; - - gpio_label = gpiochip_is_requested(chip, i); - if (gpio_label) { - seq_printf(s, "[%s] GPIO%s%d: ", - gpio_label, chip->label, i); - if (__raw_readl(pio + PIO_PSR) & mask) - seq_printf(s, "[gpio] %s\n", - at91_get_gpio_value(pin) ? - "set" : "clear"); - else - seq_printf(s, "[periph %c]\n", - peripheral_function(pio, mask)); - } - } -} - -static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - int virq; - - if (offset < chip->ngpio) - virq = irq_create_mapping(at91_gpio->domain, offset); - else - virq = -ENXIO; - - dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", - chip->label, offset + chip->base, virq); - return virq; -} - -static int __init at91_gpio_setup_clk(int idx) -{ - struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; - - /* retreive PIO controller's clock */ - at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); - if (IS_ERR(at91_gpio->clock)) { - pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx); - goto err; - } - - if (clk_prepare(at91_gpio->clock)) - goto clk_prep_err; - - /* enable PIO controller's clock */ - if (clk_enable(at91_gpio->clock)) { - pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx); - goto clk_err; - } - - return 0; - -clk_err: - clk_unprepare(at91_gpio->clock); -clk_prep_err: - clk_put(at91_gpio->clock); -err: - return -EINVAL; -} - -static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) -{ - struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; - - at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK; - at91_gpio->pioc_hwirq = pioc_hwirq; - at91_gpio->pioc_idx = idx; - - at91_gpio->regbase = ioremap(regbase, 512); - if (!at91_gpio->regbase) { - pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx); - return; - } - - if (at91_gpio_setup_clk(idx)) - goto ioremap_err; - - gpio_banks = max(gpio_banks, idx + 1); - return; - -ioremap_err: - iounmap(at91_gpio->regbase); -} - -/* - * Called from the processor-specific init to enable GPIO pin support. - */ -void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) -{ - unsigned i; - struct at91_gpio_chip *at91_gpio, *last = NULL; - - BUG_ON(nr_banks > MAX_GPIO_BANKS); - - if (of_have_populated_dt()) - return; - - for (i = 0; i < nr_banks; i++) - at91_gpio_init_one(i, data[i].regbase, data[i].id); - - for (i = 0; i < gpio_banks; i++) { - at91_gpio = &gpio_chip[i]; - - /* - * GPIO controller are grouped on some SoC: - * PIOC, PIOD and PIOE can share the same IRQ line - */ - if (last && last->pioc_hwirq == at91_gpio->pioc_hwirq) - last->next = at91_gpio; - last = at91_gpio; - - gpiochip_add(&at91_gpio->chip); - } -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/gpio.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/gpio.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/gpio.h - * - * Copyright (C) 2005 HP Labs - * - * 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. - * - */ - -#ifndef __ASM_ARCH_AT91RM9200_GPIO_H -#define __ASM_ARCH_AT91RM9200_GPIO_H - -#include <linux/kernel.h> -#include <asm/irq.h> - -#define MAX_GPIO_BANKS 5 -#define NR_BUILTIN_GPIO (MAX_GPIO_BANKS * 32) - -/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ - -#define AT91_PIN_PA0 (0x00 + 0) -#define AT91_PIN_PA1 (0x00 + 1) -#define AT91_PIN_PA2 (0x00 + 2) -#define AT91_PIN_PA3 (0x00 + 3) -#define AT91_PIN_PA4 (0x00 + 4) -#define AT91_PIN_PA5 (0x00 + 5) -#define AT91_PIN_PA6 (0x00 + 6) -#define AT91_PIN_PA7 (0x00 + 7) -#define AT91_PIN_PA8 (0x00 + 8) -#define AT91_PIN_PA9 (0x00 + 9) -#define AT91_PIN_PA10 (0x00 + 10) -#define AT91_PIN_PA11 (0x00 + 11) -#define AT91_PIN_PA12 (0x00 + 12) -#define AT91_PIN_PA13 (0x00 + 13) -#define AT91_PIN_PA14 (0x00 + 14) -#define AT91_PIN_PA15 (0x00 + 15) -#define AT91_PIN_PA16 (0x00 + 16) -#define AT91_PIN_PA17 (0x00 + 17) -#define AT91_PIN_PA18 (0x00 + 18) -#define AT91_PIN_PA19 (0x00 + 19) -#define AT91_PIN_PA20 (0x00 + 20) -#define AT91_PIN_PA21 (0x00 + 21) -#define AT91_PIN_PA22 (0x00 + 22) -#define AT91_PIN_PA23 (0x00 + 23) -#define AT91_PIN_PA24 (0x00 + 24) -#define AT91_PIN_PA25 (0x00 + 25) -#define AT91_PIN_PA26 (0x00 + 26) -#define AT91_PIN_PA27 (0x00 + 27) -#define AT91_PIN_PA28 (0x00 + 28) -#define AT91_PIN_PA29 (0x00 + 29) -#define AT91_PIN_PA30 (0x00 + 30) -#define AT91_PIN_PA31 (0x00 + 31) - -#define AT91_PIN_PB0 (0x20 + 0) -#define AT91_PIN_PB1 (0x20 + 1) -#define AT91_PIN_PB2 (0x20 + 2) -#define AT91_PIN_PB3 (0x20 + 3) -#define AT91_PIN_PB4 (0x20 + 4) -#define AT91_PIN_PB5 (0x20 + 5) -#define AT91_PIN_PB6 (0x20 + 6) -#define AT91_PIN_PB7 (0x20 + 7) -#define AT91_PIN_PB8 (0x20 + 8) -#define AT91_PIN_PB9 (0x20 + 9) -#define AT91_PIN_PB10 (0x20 + 10) -#define AT91_PIN_PB11 (0x20 + 11) -#define AT91_PIN_PB12 (0x20 + 12) -#define AT91_PIN_PB13 (0x20 + 13) -#define AT91_PIN_PB14 (0x20 + 14) -#define AT91_PIN_PB15 (0x20 + 15) -#define AT91_PIN_PB16 (0x20 + 16) -#define AT91_PIN_PB17 (0x20 + 17) -#define AT91_PIN_PB18 (0x20 + 18) -#define AT91_PIN_PB19 (0x20 + 19) -#define AT91_PIN_PB20 (0x20 + 20) -#define AT91_PIN_PB21 (0x20 + 21) -#define AT91_PIN_PB22 (0x20 + 22) -#define AT91_PIN_PB23 (0x20 + 23) -#define AT91_PIN_PB24 (0x20 + 24) -#define AT91_PIN_PB25 (0x20 + 25) -#define AT91_PIN_PB26 (0x20 + 26) -#define AT91_PIN_PB27 (0x20 + 27) -#define AT91_PIN_PB28 (0x20 + 28) -#define AT91_PIN_PB29 (0x20 + 29) -#define AT91_PIN_PB30 (0x20 + 30) -#define AT91_PIN_PB31 (0x20 + 31) - -#define AT91_PIN_PC0 (0x40 + 0) -#define AT91_PIN_PC1 (0x40 + 1) -#define AT91_PIN_PC2 (0x40 + 2) -#define AT91_PIN_PC3 (0x40 + 3) -#define AT91_PIN_PC4 (0x40 + 4) -#define AT91_PIN_PC5 (0x40 + 5) -#define AT91_PIN_PC6 (0x40 + 6) -#define AT91_PIN_PC7 (0x40 + 7) -#define AT91_PIN_PC8 (0x40 + 8) -#define AT91_PIN_PC9 (0x40 + 9) -#define AT91_PIN_PC10 (0x40 + 10) -#define AT91_PIN_PC11 (0x40 + 11) -#define AT91_PIN_PC12 (0x40 + 12) -#define AT91_PIN_PC13 (0x40 + 13) -#define AT91_PIN_PC14 (0x40 + 14) -#define AT91_PIN_PC15 (0x40 + 15) -#define AT91_PIN_PC16 (0x40 + 16) -#define AT91_PIN_PC17 (0x40 + 17) -#define AT91_PIN_PC18 (0x40 + 18) -#define AT91_PIN_PC19 (0x40 + 19) -#define AT91_PIN_PC20 (0x40 + 20) -#define AT91_PIN_PC21 (0x40 + 21) -#define AT91_PIN_PC22 (0x40 + 22) -#define AT91_PIN_PC23 (0x40 + 23) -#define AT91_PIN_PC24 (0x40 + 24) -#define AT91_PIN_PC25 (0x40 + 25) -#define AT91_PIN_PC26 (0x40 + 26) -#define AT91_PIN_PC27 (0x40 + 27) -#define AT91_PIN_PC28 (0x40 + 28) -#define AT91_PIN_PC29 (0x40 + 29) -#define AT91_PIN_PC30 (0x40 + 30) -#define AT91_PIN_PC31 (0x40 + 31) - -#define AT91_PIN_PD0 (0x60 + 0) -#define AT91_PIN_PD1 (0x60 + 1) -#define AT91_PIN_PD2 (0x60 + 2) -#define AT91_PIN_PD3 (0x60 + 3) -#define AT91_PIN_PD4 (0x60 + 4) -#define AT91_PIN_PD5 (0x60 + 5) -#define AT91_PIN_PD6 (0x60 + 6) -#define AT91_PIN_PD7 (0x60 + 7) -#define AT91_PIN_PD8 (0x60 + 8) -#define AT91_PIN_PD9 (0x60 + 9) -#define AT91_PIN_PD10 (0x60 + 10) -#define AT91_PIN_PD11 (0x60 + 11) -#define AT91_PIN_PD12 (0x60 + 12) -#define AT91_PIN_PD13 (0x60 + 13) -#define AT91_PIN_PD14 (0x60 + 14) -#define AT91_PIN_PD15 (0x60 + 15) -#define AT91_PIN_PD16 (0x60 + 16) -#define AT91_PIN_PD17 (0x60 + 17) -#define AT91_PIN_PD18 (0x60 + 18) -#define AT91_PIN_PD19 (0x60 + 19) -#define AT91_PIN_PD20 (0x60 + 20) -#define AT91_PIN_PD21 (0x60 + 21) -#define AT91_PIN_PD22 (0x60 + 22) -#define AT91_PIN_PD23 (0x60 + 23) -#define AT91_PIN_PD24 (0x60 + 24) -#define AT91_PIN_PD25 (0x60 + 25) -#define AT91_PIN_PD26 (0x60 + 26) -#define AT91_PIN_PD27 (0x60 + 27) -#define AT91_PIN_PD28 (0x60 + 28) -#define AT91_PIN_PD29 (0x60 + 29) -#define AT91_PIN_PD30 (0x60 + 30) -#define AT91_PIN_PD31 (0x60 + 31) - -#define AT91_PIN_PE0 (0x80 + 0) -#define AT91_PIN_PE1 (0x80 + 1) -#define AT91_PIN_PE2 (0x80 + 2) -#define AT91_PIN_PE3 (0x80 + 3) -#define AT91_PIN_PE4 (0x80 + 4) -#define AT91_PIN_PE5 (0x80 + 5) -#define AT91_PIN_PE6 (0x80 + 6) -#define AT91_PIN_PE7 (0x80 + 7) -#define AT91_PIN_PE8 (0x80 + 8) -#define AT91_PIN_PE9 (0x80 + 9) -#define AT91_PIN_PE10 (0x80 + 10) -#define AT91_PIN_PE11 (0x80 + 11) -#define AT91_PIN_PE12 (0x80 + 12) -#define AT91_PIN_PE13 (0x80 + 13) -#define AT91_PIN_PE14 (0x80 + 14) -#define AT91_PIN_PE15 (0x80 + 15) -#define AT91_PIN_PE16 (0x80 + 16) -#define AT91_PIN_PE17 (0x80 + 17) -#define AT91_PIN_PE18 (0x80 + 18) -#define AT91_PIN_PE19 (0x80 + 19) -#define AT91_PIN_PE20 (0x80 + 20) -#define AT91_PIN_PE21 (0x80 + 21) -#define AT91_PIN_PE22 (0x80 + 22) -#define AT91_PIN_PE23 (0x80 + 23) -#define AT91_PIN_PE24 (0x80 + 24) -#define AT91_PIN_PE25 (0x80 + 25) -#define AT91_PIN_PE26 (0x80 + 26) -#define AT91_PIN_PE27 (0x80 + 27) -#define AT91_PIN_PE28 (0x80 + 28) -#define AT91_PIN_PE29 (0x80 + 29) -#define AT91_PIN_PE30 (0x80 + 30) -#define AT91_PIN_PE31 (0x80 + 31) - -#ifndef __ASSEMBLY__ -/* setup setup routines, called from board init or driver probe() */ -extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); -extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); -extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); -extern int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div); -extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); -extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on); -extern int __init_or_module at91_disable_schmitt_trig(unsigned pin); - -/* callable at any time */ -extern int at91_set_gpio_value(unsigned pin, int value); -extern int at91_get_gpio_value(unsigned pin); - -/* callable only from core power-management code */ -extern void at91_gpio_suspend(void); -extern void at91_gpio_resume(void); - -#endif /* __ASSEMBLY__ */ - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/gsia18s.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/gsia18s.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* Buttons */ -#define GPIO_TRIG_NET_IN AT91_PIN_PB21 -#define GPIO_CARD_UNMOUNT_0 AT91_PIN_PB13 -#define GPIO_CARD_UNMOUNT_1 AT91_PIN_PB12 -#define GPIO_KEY_POWER AT91_PIN_PA25 - -/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */ -#define GS_IA18_S_PCF_GPIO_BASE0 NR_BUILTIN_GPIO -#define PCF_GPIO_HDC_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 0) -#define PCF_GPIO_WIFI_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 1) -#define PCF_GPIO_WIFI_ENABLE (GS_IA18_S_PCF_GPIO_BASE0 + 2) -#define PCF_GPIO_WIFI_RESET (GS_IA18_S_PCF_GPIO_BASE0 + 3) -#define PCF_GPIO_ETH_DETECT 4 /* this is a GPI */ -#define PCF_GPIO_GPS_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 5) -#define PCF_GPIO_GPS_STANDBY (GS_IA18_S_PCF_GPIO_BASE0 + 6) -#define PCF_GPIO_GPS_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 7) - -/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */ -#define GS_IA18_S_PCF_GPIO_BASE1 (GS_IA18_S_PCF_GPIO_BASE0 + 8) -#define PCF_GPIO_ALARM1 (GS_IA18_S_PCF_GPIO_BASE1 + 0) -#define PCF_GPIO_ALARM2 (GS_IA18_S_PCF_GPIO_BASE1 + 1) -#define PCF_GPIO_ALARM3 (GS_IA18_S_PCF_GPIO_BASE1 + 2) -#define PCF_GPIO_ALARM4 (GS_IA18_S_PCF_GPIO_BASE1 + 3) -/* bits 4, 5, 6 not used */ -#define PCF_GPIO_ALARM_V_RELAY_ON (GS_IA18_S_PCF_GPIO_BASE1 + 7) - -/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */ -#define GS_IA18_S_PCF_GPIO_BASE2 (GS_IA18_S_PCF_GPIO_BASE1 + 8) -#define PCF_GPIO_MODEM_POWER (GS_IA18_S_PCF_GPIO_BASE2 + 0) -#define PCF_GPIO_MODEM_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 3) -/* bits 1, 2, 4, 5 not used */ -#define PCF_GPIO_TRX_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 6) -/* bit 7 not used */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/hx170dec.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/hx170dec.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Decoder device driver (kernel module headers) + * + * Copyright (C) 2009 Hantro Products Oy. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _HX170DEC_H_ +#define _HX170DEC_H_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +struct core_desc +{ + __u32 id; /* id of the core */ + __u32 *regs; /* pointer to user registers */ + __u32 size; /* size of register space */ +}; + +/* Use 'k' as magic number */ +#define HX170DEC_IOC_MAGIC 'k' +/* + * S means "Set" through a ptr, + * T means "Tell" directly with the argument value + * G means "Get": reply by setting through a pointer + * Q means "Query": response is on the return value + * X means "eXchange": G and S atomically + * H means "sHift": T and Q atomically + */ + +#define HX170DEC_IOCGHWOFFSET _IOR(HX170DEC_IOC_MAGIC, 3, unsigned long *) +#define HX170DEC_IOCGHWIOSIZE _IOR(HX170DEC_IOC_MAGIC, 4, unsigned int *) + +#define HX170DEC_IOC_MC_OFFSETS _IOR(HX170DEC_IOC_MAGIC, 7, unsigned long *) +#define HX170DEC_IOC_MC_CORES _IOR(HX170DEC_IOC_MAGIC, 8, unsigned int *) +#define HX170DEC_IOCS_DEC_PUSH_REG _IOW(HX170DEC_IOC_MAGIC, 9, struct core_desc *) +#define HX170DEC_IOCS_PP_PUSH_REG _IOW(HX170DEC_IOC_MAGIC, 10, struct core_desc *) +#define HX170DEC_IOCH_DEC_RESERVE _IO(HX170DEC_IOC_MAGIC, 11) +#define HX170DEC_IOCT_DEC_RELEASE _IO(HX170DEC_IOC_MAGIC, 12) +#define HX170DEC_IOCQ_PP_RESERVE _IO(HX170DEC_IOC_MAGIC, 13) +#define HX170DEC_IOCT_PP_RELEASE _IO(HX170DEC_IOC_MAGIC, 14) +#define HX170DEC_IOCX_DEC_WAIT _IOWR(HX170DEC_IOC_MAGIC, 15, struct core_desc *) +#define HX170DEC_IOCX_PP_WAIT _IOWR(HX170DEC_IOC_MAGIC, 16, struct core_desc *) +#define HX170DEC_IOCS_DEC_PULL_REG _IOWR(HX170DEC_IOC_MAGIC, 17, struct core_desc *) +#define HX170DEC_IOCS_PP_PULL_REG _IOWR(HX170DEC_IOC_MAGIC, 18, struct core_desc *) + +#define HX170DEC_IOX_ASIC_ID _IOWR(HX170DEC_IOC_MAGIC, 20, __u32 *) + +/* + * Following are not used yet: + * + * #define HX170DEC_PP_INSTANCE _IO(HX170DEC_IOC_MAGIC, 1) + * #define HX170DEC_HW_PERFORMANCE _IO(HX170DEC_IOC_MAGIC, 2) + * #define HX170DEC_IOC_CLI _IO(HX170DEC_IOC_MAGIC, 5) + * #define HX170DEC_IOC_STI _IO(HX170DEC_IOC_MAGIC, 6) + * #define HX170DEC_IOCG_CORE_WAIT _IOR(HX170DEC_IOC_MAGIC, 19, int *) + * #define HX170DEC_DEBUG_STATUS _IO(HX170DEC_IOC_MAGIC, 29) + */ + +#define HX170DEC_IOC_MAXNR 29 + +#endif /* !_HX170DEC_H_ */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91_dbgu.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91_dbgu.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91_dbgu.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:19 @ #ifndef AT91_DBGU_H #define AT91_DBGU_H -#if !defined(CONFIG_ARCH_AT91X40) #define AT91_DBGU_CR (0x00) /* Control Register */ #define AT91_DBGU_MR (0x04) /* Mode Register */ #define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:36 @ #define AT91_DBGU_FNR (0x48) /* Force NTRST Register [SAM9 only] */ #define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */ -#endif /* AT91_DBGU */ - /* * Some AT91 parts that don't have full DEBUG units still support the ID * and extensions register. Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91_ramc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91_ramc.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91_ramc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:28 @ extern void __iomem *at91_ramc_base[]; #define AT91_MEMCTRL_SDRAMC 1 #define AT91_MEMCTRL_DDRSDR 2 -#include <mach/at91rm9200_sdramc.h> -#include <mach/at91sam9_ddrsdr.h> -#include <mach/at91sam9_sdramc.h> +#include <soc/at91/at91rm9200_sdramc.h> +#include <soc/at91/at91sam9_ddrsdr.h> +#include <soc/at91/at91sam9_sdramc.h> #endif /* __AT91_RAMC_H__ */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * - * Memory Controllers (SDRAMC only) - System peripherals registers. - * Based on AT91RM9200 datasheet revision E. - * - * 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. - */ - -#ifndef AT91RM9200_SDRAMC_H -#define AT91RM9200_SDRAMC_H - -/* SDRAM Controller registers */ -#define AT91RM9200_SDRAMC_MR 0x90 /* Mode Register */ -#define AT91RM9200_SDRAMC_MODE (0xf << 0) /* Command Mode */ -#define AT91RM9200_SDRAMC_MODE_NORMAL (0 << 0) -#define AT91RM9200_SDRAMC_MODE_NOP (1 << 0) -#define AT91RM9200_SDRAMC_MODE_PRECHARGE (2 << 0) -#define AT91RM9200_SDRAMC_MODE_LMR (3 << 0) -#define AT91RM9200_SDRAMC_MODE_REFRESH (4 << 0) -#define AT91RM9200_SDRAMC_DBW (1 << 4) /* Data Bus Width */ -#define AT91RM9200_SDRAMC_DBW_32 (0 << 4) -#define AT91RM9200_SDRAMC_DBW_16 (1 << 4) - -#define AT91RM9200_SDRAMC_TR 0x94 /* Refresh Timer Register */ -#define AT91RM9200_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ - -#define AT91RM9200_SDRAMC_CR 0x98 /* Configuration Register */ -#define AT91RM9200_SDRAMC_NC (3 << 0) /* Number of Column Bits */ -#define AT91RM9200_SDRAMC_NC_8 (0 << 0) -#define AT91RM9200_SDRAMC_NC_9 (1 << 0) -#define AT91RM9200_SDRAMC_NC_10 (2 << 0) -#define AT91RM9200_SDRAMC_NC_11 (3 << 0) -#define AT91RM9200_SDRAMC_NR (3 << 2) /* Number of Row Bits */ -#define AT91RM9200_SDRAMC_NR_11 (0 << 2) -#define AT91RM9200_SDRAMC_NR_12 (1 << 2) -#define AT91RM9200_SDRAMC_NR_13 (2 << 2) -#define AT91RM9200_SDRAMC_NB (1 << 4) /* Number of Banks */ -#define AT91RM9200_SDRAMC_NB_2 (0 << 4) -#define AT91RM9200_SDRAMC_NB_4 (1 << 4) -#define AT91RM9200_SDRAMC_CAS (3 << 5) /* CAS Latency */ -#define AT91RM9200_SDRAMC_CAS_2 (2 << 5) -#define AT91RM9200_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ -#define AT91RM9200_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ -#define AT91RM9200_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ -#define AT91RM9200_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ -#define AT91RM9200_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ -#define AT91RM9200_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ - -#define AT91RM9200_SDRAMC_SRR 0x9c /* Self Refresh Register */ -#define AT91RM9200_SDRAMC_LPR 0xa0 /* Low Power Register */ -#define AT91RM9200_SDRAMC_IER 0xa4 /* Interrupt Enable Register */ -#define AT91RM9200_SDRAMC_IDR 0xa8 /* Interrupt Disable Register */ -#define AT91RM9200_SDRAMC_IMR 0xac /* Interrupt Mask Register */ -#define AT91RM9200_SDRAMC_ISR 0xb0 /* Interrupt Status Register */ - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * Header file for the Atmel DDR/SDR SDRAM Controller - * - * Copyright (C) 2010 Atmel Corporation - * Nicolas Ferre <nicolas.ferre@atmel.com> - * - * 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. - */ -#ifndef AT91SAM9_DDRSDR_H -#define AT91SAM9_DDRSDR_H - -#define AT91_DDRSDRC_MR 0x00 /* Mode Register */ -#define AT91_DDRSDRC_MODE (0x7 << 0) /* Command Mode */ -#define AT91_DDRSDRC_MODE_NORMAL 0 -#define AT91_DDRSDRC_MODE_NOP 1 -#define AT91_DDRSDRC_MODE_PRECHARGE 2 -#define AT91_DDRSDRC_MODE_LMR 3 -#define AT91_DDRSDRC_MODE_REFRESH 4 -#define AT91_DDRSDRC_MODE_EXT_LMR 5 -#define AT91_DDRSDRC_MODE_DEEP 6 - -#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */ -#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */ - -#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */ -#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */ -#define AT91_DDRSDRC_NC_SDR8 (0 << 0) -#define AT91_DDRSDRC_NC_SDR9 (1 << 0) -#define AT91_DDRSDRC_NC_SDR10 (2 << 0) -#define AT91_DDRSDRC_NC_SDR11 (3 << 0) -#define AT91_DDRSDRC_NC_DDR9 (0 << 0) -#define AT91_DDRSDRC_NC_DDR10 (1 << 0) -#define AT91_DDRSDRC_NC_DDR11 (2 << 0) -#define AT91_DDRSDRC_NC_DDR12 (3 << 0) -#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */ -#define AT91_DDRSDRC_NR_11 (0 << 2) -#define AT91_DDRSDRC_NR_12 (1 << 2) -#define AT91_DDRSDRC_NR_13 (2 << 2) -#define AT91_DDRSDRC_NR_14 (3 << 2) -#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */ -#define AT91_DDRSDRC_CAS_2 (2 << 4) -#define AT91_DDRSDRC_CAS_3 (3 << 4) -#define AT91_DDRSDRC_CAS_25 (6 << 4) -#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */ -#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ -#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL [SAM9 Only] */ -#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */ -#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */ -#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */ - -#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ -#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ -#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */ -#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */ -#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */ -#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ -#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ -#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ -#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */ -#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ - -#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ -#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */ -#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */ -#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ -#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ - -#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register [SAM9 Only] */ -#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */ -#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */ -#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */ -#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ - -#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ -#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ -#define AT91_DDRSDRC_LPCB_DISABLE 0 -#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 -#define AT91_DDRSDRC_LPCB_POWER_DOWN 2 -#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3 -#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */ -#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */ -#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ -#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */ -#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ -#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12) -#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12) -#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12) -#define AT91_DDRSDRC_APDE (1 << 16) /* Active power down exit time */ -#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ - -#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ -#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ -#define AT91_DDRSDRC_MD_SDR 0 -#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 -#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 -#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */ -#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ -#define AT91_DDRSDRC_DBW_32BITS (0 << 4) -#define AT91_DDRSDRC_DBW_16BITS (1 << 4) - -#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ -#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ -#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ -#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ -#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ - -#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */ -#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ - -#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */ - -#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register [SAM9 Only] */ -#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */ -#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */ -#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */ - -#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register [SAM9 Only] */ -#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ -#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/at91sam9_sdramc.h - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * SDRAM Controllers (SDRAMC) - System peripherals registers. - * Based on AT91SAM9261 datasheet revision D. - * - * 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. - */ - -#ifndef AT91SAM9_SDRAMC_H -#define AT91SAM9_SDRAMC_H - -/* SDRAM Controller (SDRAMC) registers */ -#define AT91_SDRAMC_MR 0x00 /* SDRAM Controller Mode Register */ -#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ -#define AT91_SDRAMC_MODE_NORMAL 0 -#define AT91_SDRAMC_MODE_NOP 1 -#define AT91_SDRAMC_MODE_PRECHARGE 2 -#define AT91_SDRAMC_MODE_LMR 3 -#define AT91_SDRAMC_MODE_REFRESH 4 -#define AT91_SDRAMC_MODE_EXT_LMR 5 -#define AT91_SDRAMC_MODE_DEEP 6 - -#define AT91_SDRAMC_TR 0x04 /* SDRAM Controller Refresh Timer Register */ -#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */ - -#define AT91_SDRAMC_CR 0x08 /* SDRAM Controller Configuration Register */ -#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ -#define AT91_SDRAMC_NC_8 (0 << 0) -#define AT91_SDRAMC_NC_9 (1 << 0) -#define AT91_SDRAMC_NC_10 (2 << 0) -#define AT91_SDRAMC_NC_11 (3 << 0) -#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ -#define AT91_SDRAMC_NR_11 (0 << 2) -#define AT91_SDRAMC_NR_12 (1 << 2) -#define AT91_SDRAMC_NR_13 (2 << 2) -#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ -#define AT91_SDRAMC_NB_2 (0 << 4) -#define AT91_SDRAMC_NB_4 (1 << 4) -#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ -#define AT91_SDRAMC_CAS_1 (1 << 5) -#define AT91_SDRAMC_CAS_2 (2 << 5) -#define AT91_SDRAMC_CAS_3 (3 << 5) -#define AT91_SDRAMC_DBW (1 << 7) /* Data Bus Width */ -#define AT91_SDRAMC_DBW_32 (0 << 7) -#define AT91_SDRAMC_DBW_16 (1 << 7) -#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */ -#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */ -#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */ -#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */ -#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */ -#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */ - -#define AT91_SDRAMC_LPR 0x10 /* SDRAM Controller Low Power Register */ -#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */ -#define AT91_SDRAMC_LPCB_DISABLE 0 -#define AT91_SDRAMC_LPCB_SELF_REFRESH 1 -#define AT91_SDRAMC_LPCB_POWER_DOWN 2 -#define AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3 -#define AT91_SDRAMC_PASR (7 << 4) /* Partial Array Self Refresh */ -#define AT91_SDRAMC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ -#define AT91_SDRAMC_DS (3 << 10) /* Drive Strength */ -#define AT91_SDRAMC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ -#define AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES (0 << 12) -#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12) -#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12) - -#define AT91_SDRAMC_IER 0x14 /* SDRAM Controller Interrupt Enable Register */ -#define AT91_SDRAMC_IDR 0x18 /* SDRAM Controller Interrupt Disable Register */ -#define AT91_SDRAMC_IMR 0x1C /* SDRAM Controller Interrupt Mask Register */ -#define AT91_SDRAMC_ISR 0x20 /* SDRAM Controller Interrupt Status Register */ -#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */ - -#define AT91_SDRAMC_MDR 0x24 /* SDRAM Memory Device Register */ -#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */ -#define AT91_SDRAMC_MD_SDRAM 0 -#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/at91x40.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/at91x40.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/include/mach/at91x40.h - * - * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> - * - * 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. - */ - -#ifndef AT91X40_H -#define AT91X40_H - -/* - * IRQ list. - */ -#define AT91X40_ID_USART0 2 /* USART port 0 */ -#define AT91X40_ID_USART1 3 /* USART port 1 */ -#define AT91X40_ID_TC0 4 /* Timer/Counter 0 */ -#define AT91X40_ID_TC1 5 /* Timer/Counter 1*/ -#define AT91X40_ID_TC2 6 /* Timer/Counter 2*/ -#define AT91X40_ID_WD 7 /* Watchdog? */ -#define AT91X40_ID_PIOA 8 /* Parallel IO Controller A */ - -#define AT91X40_ID_IRQ0 16 /* External IRQ 0 */ -#define AT91X40_ID_IRQ1 17 /* External IRQ 1 */ -#define AT91X40_ID_IRQ2 18 /* External IRQ 2 */ - -/* - * System Peripherals - */ -#define AT91_BASE_SYS 0xffc00000 - -#define AT91_EBI 0xffe00000 /* External Bus Interface */ -#define AT91_SF 0xfff00000 /* Special Function */ -#define AT91_USART1 0xfffcc000 /* USART 1 */ -#define AT91_USART0 0xfffd0000 /* USART 0 */ -#define AT91_TC 0xfffe0000 /* Timer Counter */ -#define AT91_PIOA 0xffff0000 /* PIO Controller A */ -#define AT91_PS 0xffff4000 /* Power Save */ -#define AT91_WD 0xffff8000 /* Watchdog Timer */ - -/* - * The AT91x40 series doesn't have a debug unit like the other AT91 parts. - * But it does have a chip identify register and extension ID, so define at - * least these here. - */ -#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */ -#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */ - -/* - * Support defines for the simple Power Controller module. - */ -#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */ -#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */ - -#define AT91X40_MASTER_CLOCK 40000000 - -#endif /* AT91X40_H */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/cpu.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/cpu.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/cpu.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:65 @ #define ARCH_EXID_SAMA5D43 0x00000003 #define ARCH_EXID_SAMA5D44 0x00000004 -#define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/hardware.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/hardware.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/hardware.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:27 @ /* sama5d4 */ #define AT91_BASE_DBGU2 0xfc069000 -#if defined(CONFIG_ARCH_AT91X40) -#include <mach/at91x40.h> -#else #include <mach/at91rm9200.h> #include <mach/at91sam9260.h> #include <mach/at91sam9261.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:51 @ */ #define AT91_BASE_SYS 0xffffc000 -#endif - /* * On sama5d4 there is no system controller, we map some needed peripherals */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:130 @ * called as part of the generic suspend/resume path. */ #ifndef __ASSEMBLY__ -#ifdef CONFIG_PINCTRL_AT91 extern void at91_pinctrl_gpio_suspend(void); extern void at91_pinctrl_gpio_resume(void); -#else -static inline void at91_pinctrl_gpio_suspend(void) {} -static inline void at91_pinctrl_gpio_resume(void) {} -#endif #endif #endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/sama5d3.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/sama5d3.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/sama5d3.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:66 @ #define SAMA5D3_ID_TDES 44 /* Triple Data Encryption Standard */ #define SAMA5D3_ID_TRNG 45 /* True Random Generator Number */ #define SAMA5D3_ID_IRQ0 47 /* Advanced Interrupt Controller (IRQ0) */ +#define SAMA5D3_ID_MPDDRC 49 /* MPDDR controller */ /* * User Peripheral physical base addresses. Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/sama5d4.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/sama5d4.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/sama5d4.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:17 @ #define SAMA5D4_H /* + * Peripheral identifiers/interrupts. + */ +#define SAMA5D4_ID_MPDDRC 16 /* MPDDR controller */ + +/* * User Peripheral physical base addresses. */ #define SAMA5D4_BASE_USART3 0xfc00c000 /* (USART3 non-secure) Base Address */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/uncompress.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/include/mach/uncompress.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/include/mach/uncompress.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:34 @ void __iomem *at91_uart; -#if !defined(CONFIG_ARCH_AT91X40) static const u32 uarts_rm9200[] = { AT91_BASE_DBGU0, AT91RM9200_BASE_US0, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:190 @ static inline void arch_decomp_setup(voi at91_uart = NULL; } -#else -static inline void arch_decomp_setup(void) -{ - at91_uart = NULL; -} -#endif /* * The following code assumes the serial port has already been Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/irq.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/irq.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * linux/arch/arm/mach-at91/irq.c - * - * Copyright (C) 2004 SAN People - * Copyright (C) 2004 ATMEL - * Copyright (C) Rick Bronson - * - * 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 - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/bitmap.h> -#include <linux/types.h> -#include <linux/irq.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <linux/irqdomain.h> -#include <linux/err.h> -#include <linux/slab.h> - -#include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/setup.h> - -#include <asm/exception.h> -#include <asm/mach/arch.h> -#include <asm/mach/irq.h> -#include <asm/mach/map.h> - -#include "at91_aic.h" - -void __iomem *at91_aic_base; -static struct irq_domain *at91_aic_domain; -static struct device_node *at91_aic_np; -static unsigned int n_irqs = NR_AIC_IRQS; - -#ifdef CONFIG_PM - -static unsigned long *wakeups; -static unsigned long *backups; - -#define set_backup(bit) set_bit(bit, backups) -#define clear_backup(bit) clear_bit(bit, backups) - -static int at91_aic_pm_init(void) -{ - backups = kzalloc(BITS_TO_LONGS(n_irqs) * sizeof(*backups), GFP_KERNEL); - if (!backups) - return -ENOMEM; - - wakeups = kzalloc(BITS_TO_LONGS(n_irqs) * sizeof(*backups), GFP_KERNEL); - if (!wakeups) { - kfree(backups); - return -ENOMEM; - } - - return 0; -} - -static int at91_aic_set_wake(struct irq_data *d, unsigned value) -{ - if (unlikely(d->hwirq >= n_irqs)) - return -EINVAL; - - if (value) - set_bit(d->hwirq, wakeups); - else - clear_bit(d->hwirq, wakeups); - - return 0; -} - -void at91_irq_suspend(void) -{ - at91_aic_write(AT91_AIC_IDCR, *backups); - at91_aic_write(AT91_AIC_IECR, *wakeups); -} - -void at91_irq_resume(void) -{ - at91_aic_write(AT91_AIC_IDCR, *wakeups); - at91_aic_write(AT91_AIC_IECR, *backups); -} - -#else -static inline int at91_aic_pm_init(void) -{ - return 0; -} - -#define set_backup(bit) -#define clear_backup(bit) -#define at91_aic_set_wake NULL - -#endif /* CONFIG_PM */ - -asmlinkage void __exception_irq_entry -at91_aic_handle_irq(struct pt_regs *regs) -{ - u32 irqnr; - u32 irqstat; - - irqnr = at91_aic_read(AT91_AIC_IVR); - irqstat = at91_aic_read(AT91_AIC_ISR); - - /* - * ISR value is 0 when there is no current interrupt or when there is - * a spurious interrupt - */ - if (!irqstat) - at91_aic_write(AT91_AIC_EOICR, 0); - else - handle_IRQ(irqnr, regs); -} - -static void at91_aic_mask_irq(struct irq_data *d) -{ - /* Disable interrupt on AIC */ - at91_aic_write(AT91_AIC_IDCR, 1 << d->hwirq); - /* Update ISR cache */ - clear_backup(d->hwirq); -} - -static void at91_aic_unmask_irq(struct irq_data *d) -{ - /* Enable interrupt on AIC */ - at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); - /* Update ISR cache */ - set_backup(d->hwirq); -} - -static void at91_aic_eoi(struct irq_data *d) -{ - /* - * Mark end-of-interrupt on AIC, the controller doesn't care about - * the value written. Moreover it's a write-only register. - */ - at91_aic_write(AT91_AIC_EOICR, 0); -} - -static unsigned long *at91_extern_irq; - -u32 at91_get_extern_irq(void) -{ - if (!at91_extern_irq) - return 0; - return *at91_extern_irq; -} - -#define is_extern_irq(hwirq) test_bit(hwirq, at91_extern_irq) - -static int at91_aic_compute_srctype(struct irq_data *d, unsigned type) -{ - int srctype; - - switch (type) { - case IRQ_TYPE_LEVEL_HIGH: - srctype = AT91_AIC_SRCTYPE_HIGH; - break; - case IRQ_TYPE_EDGE_RISING: - srctype = AT91_AIC_SRCTYPE_RISING; - break; - case IRQ_TYPE_LEVEL_LOW: - if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_LOW; - else - srctype = -EINVAL; - break; - case IRQ_TYPE_EDGE_FALLING: - if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_FALLING; - else - srctype = -EINVAL; - break; - default: - srctype = -EINVAL; - } - - return srctype; -} - -static int at91_aic_set_type(struct irq_data *d, unsigned type) -{ - unsigned int smr; - int srctype; - - srctype = at91_aic_compute_srctype(d, type); - if (srctype < 0) - return srctype; - - smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); - - return 0; -} - -static struct irq_chip at91_aic_chip = { - .name = "AIC", - .irq_mask = at91_aic_mask_irq, - .irq_unmask = at91_aic_unmask_irq, - .irq_set_type = at91_aic_set_type, - .irq_set_wake = at91_aic_set_wake, - .irq_eoi = at91_aic_eoi, -}; - -static void __init at91_aic_hw_init(unsigned int spu_vector) -{ - int i; - - /* - * Perform 8 End Of Interrupt Command to make sure AIC - * will not Lock out nIRQ - */ - for (i = 0; i < 8; i++) - at91_aic_write(AT91_AIC_EOICR, 0); - - /* - * Spurious Interrupt ID in Spurious Vector Register. - * When there is no current interrupt, the IRQ Vector Register - * reads the value stored in AIC_SPU - */ - at91_aic_write(AT91_AIC_SPU, spu_vector); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_aic_write(AT91_AIC_DCR, 0); - - /* Disable and clear all interrupts initially */ - at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); -} - -/* - * Initialize the AIC interrupt controller. - */ -void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask) -{ - unsigned int i; - int irq_base; - - at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) - * sizeof(*at91_extern_irq), GFP_KERNEL); - - if (at91_aic_pm_init() || at91_extern_irq == NULL) - panic("Unable to allocate bit maps\n"); - - *at91_extern_irq = ext_irq_mask; - - at91_aic_base = ioremap(AT91_AIC, 512); - if (!at91_aic_base) - panic("Unable to ioremap AIC registers\n"); - - /* Add irq domain for AIC */ - irq_base = irq_alloc_descs(-1, 0, n_irqs, 0); - if (irq_base < 0) { - WARN(1, "Cannot allocate irq_descs, assuming pre-allocated\n"); - irq_base = 0; - } - at91_aic_domain = irq_domain_add_legacy(at91_aic_np, n_irqs, - irq_base, 0, - &irq_domain_simple_ops, NULL); - - if (!at91_aic_domain) - panic("Unable to add AIC irq domain\n"); - - irq_set_default_host(at91_aic_domain); - - /* - * The IVR is used by macro get_irqnr_and_base to read and verify. - * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. - */ - for (i = 0; i < n_irqs; i++) { - /* Put hardware irq number in Source Vector Register: */ - at91_aic_write(AT91_AIC_SVR(i), NR_IRQS_LEGACY + i); - /* Active Low interrupt, with the specified priority */ - at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); - irq_set_chip_and_handler(NR_IRQS_LEGACY + i, &at91_aic_chip, handle_fasteoi_irq); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } - - at91_aic_hw_init(n_irqs); -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/Kconfig +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:18 @ config HAVE_AT91_DBGU1 config HAVE_AT91_DBGU2 bool -config AT91_USE_OLD_CLK - bool - -config AT91_PMC_UNIT - bool - default !ARCH_AT91X40 - config COMMON_CLK_AT91 bool - default AT91_PMC_UNIT && USE_OF && !AT91_USE_OLD_CLK select COMMON_CLK -config OLD_CLK_AT91 - bool - default AT91_PMC_UNIT && AT91_USE_OLD_CLK - -config OLD_IRQ_AT91 - bool - select MULTI_IRQ_HANDLER - select SPARSE_IRQ - config HAVE_AT91_SMD bool @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:30 @ config HAVE_AT91_H32MX config SOC_AT91SAM9 bool - select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 + select ATMEL_AIC_IRQ + select COMMON_CLK_AT91 select CPU_ARM926T select GENERIC_CLOCKEVENTS - select MEMORY if USE_OF - select ATMEL_SDRAMC if USE_OF + select MEMORY + select ATMEL_SDRAMC + select SRAM if PM config SOC_SAMA5 bool select ATMEL_AIC5_IRQ + select COMMON_CLK_AT91 select CPU_V7 select GENERIC_CLOCKEVENTS - select USE_OF select MEMORY select ATMEL_SDRAMC + select PHYLIB if NETDEVICES + select SRAM if PM menu "Atmel AT91 System-on-Chip" @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:55 @ choice prompt "Core type" -config ARCH_AT91X40 - bool "ARM7 AT91X40" - depends on !MMU - select CPU_ARM7TDMI - select ARCH_USES_GETTIMEOFFSET - select OLD_IRQ_AT91 - - help - Select this if you are using one of Atmel's AT91X40 SoC. - config SOC_SAM_V4_V5 bool "ARM9 AT91SAM9/AT91RM9200" help @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:102 @ endif if SOC_SAM_V4_V5 config SOC_AT91RM9200 bool "AT91RM9200" - select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 + select ATMEL_AIC_IRQ + select COMMON_CLK_AT91 select CPU_ARM920T select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 select HAVE_AT91_USB_CLK + select SRAM if PM config SOC_AT91SAM9260 bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:180 @ config SOC_AT91SAM9N12 # ---------------------------------------------------------- endif # SOC_SAM_V4_V5 - -if SOC_SAM_V4_V5 || ARCH_AT91X40 -source arch/arm/mach-at91/Kconfig.non_dt -endif - -comment "Generic Board Type" - config MACH_AT91RM9200_DT - bool "Atmel AT91RM9200 Evaluation Kits with device-tree support" - depends on SOC_AT91RM9200 - select USE_OF - help - Select this if you want to experiment device-tree with - an Atmel RM9200 Evaluation Kit. + def_bool SOC_AT91RM9200 config MACH_AT91SAM9_DT - bool "Atmel AT91SAM Evaluation Kits with device-tree support" - depends on SOC_AT91SAM9 - select USE_OF - help - Select this if you want to experiment device-tree with - an Atmel Evaluation Kit. - -config MACH_SAMA5_DT - bool "Atmel SAMA5 Evaluation Kits with device-tree support" - depends on SOC_SAMA5 - select USE_OF - select PHYLIB if NETDEVICES - help - Select this if you want to experiment device-tree with - an Atmel Evaluation Kit. + def_bool SOC_AT91SAM9 # ---------------------------------------------------------- comment "AT91 Feature Selections" -config AT91_SLOW_CLOCK - bool "Suspend-to-RAM disables main oscillator" - depends on SUSPEND - help - Select this if you want Suspend-to-RAM to save the most power - possible (without powering off the CPU) by disabling the PLLs - and main oscillator so that only the 32 KiHz clock is available. - - When only that slow-clock is available, some peripherals lose - functionality. Many can't issue wakeup events unless faster - clocks are available. Some lose their operating state and - need to be completely re-initialized. - config AT91_TIMER_HZ int "Kernel HZ (jiffies per second)" range 32 1024 depends on ARCH_AT91 - default "128" if ARCH_AT91RM9200 + default "128" if SOC_AT91RM9200 default "100" help On AT91rm9200 chips where you're using a system clock derived Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Kconfig.non_dt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/Kconfig.non_dt +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -menu "Atmel Non-DT world" - -config HAVE_AT91_DATAFLASH_CARD - bool - -choice - prompt "Atmel AT91 Processor Devices for non DT boards" - depends on !ARCH_AT91X40 - -config ARCH_AT91_NONE - bool "None" - -config ARCH_AT91RM9200 - bool "AT91RM9200" - select SOC_AT91RM9200 - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -config ARCH_AT91SAM9260 - bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" - select SOC_AT91SAM9260 - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -config ARCH_AT91SAM9261 - bool "AT91SAM9261 or AT91SAM9G10" - select SOC_AT91SAM9261 - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -config ARCH_AT91SAM9263 - bool "AT91SAM9263" - select SOC_AT91SAM9263 - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -config ARCH_AT91SAM9RL - bool "AT91SAM9RL" - select SOC_AT91SAM9RL - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -config ARCH_AT91SAM9G45 - bool "AT91SAM9G45" - select SOC_AT91SAM9G45 - select AT91_USE_OLD_CLK - select OLD_IRQ_AT91 - -endchoice - -config ARCH_AT91SAM9G20 - bool - select ARCH_AT91SAM9260 - -config ARCH_AT91SAM9G10 - bool - select ARCH_AT91SAM9261 - -# ---------------------------------------------------------- - -if ARCH_AT91RM9200 - -comment "AT91RM9200 Board Type" - -config MACH_ONEARM - bool "Ajeco 1ARM Single Board Computer" - help - Select this if you are using Ajeco's 1ARM Single Board Computer. - <http://www.ajeco.fi/> - -config MACH_AT91RM9200EK - bool "Atmel AT91RM9200-EK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507> - -config MACH_CSB337 - bool "Cogent CSB337" - help - Select this if you are using Cogent's CSB337 board. - <http://www.cogcomp.com/csb_csb337.htm> - -config MACH_CSB637 - bool "Cogent CSB637" - help - Select this if you are using Cogent's CSB637 board. - <http://www.cogcomp.com/csb_csb637.htm> - -config MACH_CARMEVA - bool "Conitec ARM&EVA" - help - Select this if you are using Conitec's AT91RM9200-MCU-Module. - <http://www.conitec.net/english/linuxboard.php> - -config MACH_ATEB9200 - bool "Embest ATEB9200" - help - Select this if you are using Embest's ATEB9200 board. - <http://www.embedinfo.com/english/product/ATEB9200.asp> - -config MACH_KB9200 - bool "KwikByte KB920x" - help - Select this if you are using KwikByte's KB920x board. - <http://www.kwikbyte.com/KB9202.html> - -config MACH_PICOTUX2XX - bool "picotux 200" - help - Select this if you are using a picotux 200. - <http://www.picotux.com/> - -config MACH_KAFA - bool "Sperry-Sun KAFA board" - help - Select this if you are using Sperry-Sun's KAFA board. - -config MACH_ECBAT91 - bool "emQbit ECB_AT91 SBC" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using emQbit's ECB_AT91 board. - <http://wiki.emqbit.com/free-ecb-at91> - -config MACH_YL9200 - bool "ucDragon YL-9200" - help - Select this if you are using the ucDragon YL-9200 board. - -config MACH_CPUAT91 - bool "Eukrea CPUAT91" - help - Select this if you are using the Eukrea Electromatique's - CPUAT91 board <http://www.eukrea.com/>. - -config MACH_ECO920 - bool "eco920" - help - Select this if you are using the eco920 board -endif - -# ---------------------------------------------------------- - -if ARCH_AT91SAM9260 - -comment "AT91SAM9260 Variants" - -comment "AT91SAM9260 / AT91SAM9XE Board Type" - -config MACH_AT91SAM9260EK - bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> - -config MACH_CAM60 - bool "KwikByte KB9260 (CAM60) board" - help - Select this if you are using KwikByte's KB9260 (CAM60) board based on the Atmel AT91SAM9260. - <http://www.kwikbyte.com/KB9260.html> - -config MACH_SAM9_L9260 - bool "Olimex SAM9-L9260 board" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260. - <http://www.olimex.com/dev/sam9-L9260.html> - -config MACH_AFEB9260 - bool "Custom afeb9260 board v1" - help - Select this if you are using custom afeb9260 board based on - open hardware design. Select this for revision 1 of the board. - <svn://194.85.238.22/home/users/george/svn/arm9eb> - <http://groups.google.com/group/arm9fpga-evolution-board> - -config MACH_CPU9260 - bool "Eukrea CPU9260 board" - help - Select this if you are using a Eukrea Electromatique's - CPU9260 Board <http://www.eukrea.com/> - -config MACH_FLEXIBITY - bool "Flexibity Connect board" - help - Select this if you are using Flexibity Connect board - <http://www.flexibity.com> - -comment "AT91SAM9G20 Board Type" - -config MACH_AT91SAM9G20EK - bool "Atmel AT91SAM9G20-EK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit - that embeds only one SD/MMC slot. - -config MACH_AT91SAM9G20EK_2MMC - depends on MACH_AT91SAM9G20EK - bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots" - help - Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit - with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and - onwards. - <http://www.atmel.com/tools/SAM9G20-EK.aspx> - -config MACH_CPU9G20 - bool "Eukrea CPU9G20 board" - help - Select this if you are using a Eukrea Electromatique's - CPU9G20 Board <http://www.eukrea.com/> - -config MACH_PORTUXG20 - bool "taskit PortuxG20" - help - Select this if you are using taskit's PortuxG20. - <http://www.taskit.de/en/> - -config MACH_STAMP9G20 - bool "taskit Stamp9G20 CPU module" - help - Select this if you are using taskit's Stamp9G20 CPU module on its - evaluation board. - <http://www.taskit.de/en/> - -config MACH_PCONTROL_G20 - bool "PControl G20 CPU module" - help - Select this if you are using taskit's Stamp9G20 CPU module on this - carrier board, being the decentralized unit of a building automation - system; featuring nvram, eth-switch, iso-rs485, display, io - -config MACH_GSIA18S - bool "GS_IA18_S board" - help - This enables support for the GS_IA18_S board - produced by GeoSIG Ltd company. This is an internet accelerograph. - <http://www.geosig.com> - -config MACH_SNAPPER_9260 - bool "Bluewater Systems Snapper 9260/9G20 module" - help - Select this if you are using the Bluewater Systems Snapper 9260 or - Snapper 9G20 modules. - <http://www.bluewatersys.com/> -endif - -# ---------------------------------------------------------- - -if ARCH_AT91SAM9261 - -comment "AT91SAM9261 Board Type" - -config MACH_AT91SAM9261EK - bool "Atmel AT91SAM9261-EK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> - -comment "AT91SAM9G10 Board Type" - -config MACH_AT91SAM9G10EK - bool "Atmel AT91SAM9G10-EK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588> - -endif - -# ---------------------------------------------------------- - -if ARCH_AT91SAM9263 - -comment "AT91SAM9263 Board Type" - -config MACH_AT91SAM9263EK - bool "Atmel AT91SAM9263-EK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057> - -endif - -# ---------------------------------------------------------- - -if ARCH_AT91SAM9RL - -comment "AT91SAM9RL Board Type" - -config MACH_AT91SAM9RLEK - bool "Atmel AT91SAM9RL-EK Evaluation Kit" - help - Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit. - -endif - -# ---------------------------------------------------------- - -if ARCH_AT91SAM9G45 - -comment "AT91SAM9G45 Board Type" - -config MACH_AT91SAM9M10G45EK - bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" - help - Select this if you are using Atmel's AT91SAM9M10G45-EK Evaluation Kit. - Those boards can be populated with any SoC of AT91SAM9G45 or AT91SAM9M10 - families: AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. - <http://www.atmel.com/tools/SAM9M10-G45-EK.aspx> - -endif - -# ---------------------------------------------------------- - -if ARCH_AT91X40 - -comment "AT91X40 Board Type" - -config MACH_AT91EB01 - bool "Atmel AT91EB01 Evaluation Kit" - help - Select this if you are using Atmel's AT91EB01 Evaluation Kit. - It is also a popular target for simulators such as GDB's - ARM simulator (commonly known as the ARMulator) and the - Skyeye simulator. - -endif - -# ---------------------------------------------------------- - -comment "AT91 Board Options" - -config MTD_AT91_DATAFLASH_CARD - bool "Enable DataFlash Card support" - depends on HAVE_AT91_DATAFLASH_CARD - help - Enable support for the DataFlash card. - -endmenu Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/leds.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/leds.c +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * LED driver for Atmel AT91-based boards. - * - * Copyright (C) SAN People (Pty) 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. -*/ - -#include <linux/gpio.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -#include "board.h" -#include "gpio.h" - - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_NEW_LEDS) - -/* - * New cross-platform LED support. - */ - -static struct gpio_led_platform_data led_data; - -static struct platform_device at91_gpio_leds_device = { - .name = "leds-gpio", - .id = -1, - .dev.platform_data = &led_data, -}; - -void __init at91_gpio_leds(struct gpio_led *leds, int nr) -{ - int i; - - if (!nr) - return; - - for (i = 0; i < nr; i++) - at91_set_gpio_output(leds[i].gpio, leds[i].active_low); - - led_data.leds = leds; - led_data.num_leds = nr; - platform_device_register(&at91_gpio_leds_device); -} - -#else -void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} -#endif - Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/Makefile +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5 @ # Makefile for the linux kernel. # -obj-y := gpio.o setup.o sysirq_mask.o +obj-y := setup.o sysirq_mask.o -obj-$(CONFIG_OLD_IRQ_AT91) += irq.o -obj-$(CONFIG_OLD_CLK_AT91) += clock.o obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o # CPU-specific support @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:19 @ obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o -obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o - -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261_devices.o -obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263_devices.o -obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45_devices.o -obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o - -# AT91RM9200 board-specific support -obj-$(CONFIG_MACH_ONEARM) += board-1arm.o -obj-$(CONFIG_MACH_AT91RM9200EK) += board-rm9200ek.o -obj-$(CONFIG_MACH_CSB337) += board-csb337.o -obj-$(CONFIG_MACH_CSB637) += board-csb637.o -obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o -obj-$(CONFIG_MACH_KB9200) += board-kb9202.o -obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o -obj-$(CONFIG_MACH_KAFA) += board-kafa.o -obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o -obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o -obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o -obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o -obj-$(CONFIG_MACH_ECO920) += board-eco920.o - -# AT91SAM9260 board-specific support -obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o -obj-$(CONFIG_MACH_CAM60) += board-cam60.o -obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o -obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o -obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o -obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o - -# AT91SAM9261 board-specific support -obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o -obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o - -# AT91SAM9263 board-specific support -obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o - -# AT91SAM9RL board-specific support -obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o - -# AT91SAM9G20 board-specific support -obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o -obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o -obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o -obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o -obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o -obj-$(CONFIG_MACH_GSIA18S) += board-gsia18s.o board-stamp9g20.o - -# AT91SAM9260/AT91SAM9G20 board-specific support -obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o - -# AT91SAM9G45 board-specific support -obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o +obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o memalloc.o vdec_g1.o # AT91SAM board with device-tree obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o # SAMA5 board with device-tree -obj-$(CONFIG_MACH_SAMA5_DT) += board-dt-sama5.o - -# AT91X40 board-specific support -obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o - -# Drivers -obj-y += leds.o +obj-$(CONFIG_SOC_SAMA5) += board-dt-sama5.o # Power Management obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o +obj-$(CONFIG_PM) += pm_suspend.o ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Makefile.boot =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/Makefile.boot +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/Makefile.boot @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:6 @ # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM -ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70410000 -else zreladdr-y += 0x20008000 params_phys-y := 0x20000100 initrd_phys-y := 0x20410000 -endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/memalloc.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/memalloc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Physically contiguous memory allocator + * + * Copyright (C) 2009 Hantro Products Oy. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/module.h> +#include <linux/dma-mapping.h> /* dma_zalloc_coherent, dma_free_coherent */ +#include <linux/fs.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/uaccess.h> + +#include "memalloc.h" + +struct memalloc_drv { + struct class *class; + struct device *dev; + int major; + struct list_head opened; /* list of opened files (memalloc_file_context) */ + spinlock_t lock; +}; + +struct memalloc_file_context { + struct list_head n; + struct memalloc_drv *parent; + struct list_head blocks; /* list of allocated blocks (mem_block) */ + spinlock_t lock; + //unsigned int num_blocks; +}; + +struct memalloc_block { + struct list_head n; + dma_addr_t dma_handle; + void *virt_addr; + size_t size; /* page aligned */ + int method; +}; + +static struct memalloc_drv memalloc_ing = { + .opened = LIST_HEAD_INIT(memalloc_ing.opened), + .lock = __SPIN_LOCK_UNLOCKED(memalloc_ing.lock), +}; + +/** + * allocate_large_block - Allocate a physically contiguous memory area + * + * @param dev driver device node + * @param pp_block Result block struct address + * @param p_size Wished size. Output is rounded up to page size (often something like 4k) + * + * @return 0 on success, negative value on error + */ +static int allocate_large_block(struct device *dev, struct memalloc_block **pp_block, size_t *p_size) +{ + struct memalloc_block *p; + + p = kmalloc(sizeof(struct memalloc_block), GFP_KERNEL); + if (p == NULL) { + dev_info(dev, "unable to alloc block struct.\n"); + return -ENOMEM; + } + + p->size = PAGE_ALIGN(*p_size); + + /* Multiple of PAGE_SIZE */ + p->virt_addr = dma_zalloc_coherent(dev, p->size, &p->dma_handle, GFP_KERNEL); + if (!p->virt_addr) { + dev_err(dev, "large alloc failed (%d)\n", p->size); + kfree(p); + return -ENOMEM; + } + + dev_dbg(dev, "large alloc ok: VA=%p PA=0x%llx SZ=%d (requested %d)\n", + p->virt_addr, (unsigned long long)p->dma_handle, p->size, *p_size); + + *p_size = p->size; + *pp_block = p; + return 0; +} + +static int free_large_block(struct device *dev, struct memalloc_block *p) +{ + dev_dbg(dev, "large free: VA=%p\n", p->virt_addr); + dma_free_coherent(dev, p->size, p->virt_addr, p->dma_handle); + kfree(p); + return 0; +} + +static long memalloc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct memalloc_file_context *fc = filp->private_data; + struct memalloc_drv *m = fc->parent; + + int ret = -EFAULT; + MemallocParams mem_params; + struct memalloc_block *p; + size_t sz; + + if (!filp || arg == 0) + return ret; + + switch (cmd) { + case MEMALLOC_IOCXGETBUFFER: + spin_lock(&fc->lock); + if (copy_from_user(&mem_params, (MemallocParams *)arg, sizeof(mem_params))) + dev_dbg(m->dev, "copy_from_user failed\n"); + + sz = mem_params.size; + ret = allocate_large_block(m->dev, &p, &sz); + + if (!ret) { + mem_params.busAddress = (unsigned long)p->dma_handle; /* should be 64-bit! */ + mem_params.size = sz; + if (copy_to_user((MemallocParams *)arg, &mem_params, sizeof(mem_params))) + dev_dbg(m->dev, "copy_to_user failed\n"); + + list_add(&p->n, &fc->blocks); + } + spin_unlock(&fc->lock); + break; + + case MEMALLOC_IOCSFREEBUFFER: + ret = -EINVAL; + spin_lock(&fc->lock); + __get_user(mem_params.busAddress, (unsigned long *)arg); + + /* find memalloc_block */ + list_for_each_entry(p, &fc->blocks, n) { + if ((unsigned long)p->dma_handle == mem_params.busAddress) { + list_del(&p->n); + free_large_block(m->dev, p); + ret = 0; + break; + } + } + spin_unlock(&fc->lock); + break; + + default: + ret = -ENOIOCTLCMD; + } + return ret; +} + +static int memalloc_open(struct inode *inode, struct file *filp) +{ + struct memalloc_file_context *fc; + struct memalloc_drv *m = &memalloc_ing; + int dev = iminor(inode); + + if (dev != 0) { + dev_warn(m->dev, "unsupported minor (%d).\n", dev); + return -EINVAL; + } + + fc = kmalloc(sizeof(struct memalloc_file_context), GFP_KERNEL); + if (fc == NULL) { + dev_err(m->dev, "unable to alloc struct.\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&fc->blocks); + spin_lock_init(&fc->lock); + fc->parent = m; + + filp->private_data = fc; + + spin_lock(&m->lock); + list_add_tail(&fc->n, &m->opened); + spin_unlock(&m->lock); + + dev_dbg(m->dev, "file open (%p)\n", fc); + return 0; +} + +static int memalloc_release(struct inode *inode, struct file *filp) +{ + struct memalloc_file_context *fc = filp->private_data; + struct memalloc_drv *m = fc->parent; + struct memalloc_block *p, *tmp; + + list_for_each_entry_safe(p, tmp, &fc->blocks, n) { + list_del(&p->n); + free_large_block(m->dev, p); + } + + spin_lock(&m->lock); + list_del(&fc->n); + spin_unlock(&m->lock); + + kfree(fc); + + dev_dbg(m->dev, "file release (%p)\n", fc); + return 0; +} + +static const struct vm_operations_struct mmap_mem_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys +#endif +}; + +/* This function is based on mmap_mem (drivers/char/mem.c) */ +static int memalloc_mmap (struct file *filp, struct vm_area_struct *vma) +{ + struct memalloc_file_context *fc = filp->private_data; + struct memalloc_block *p; + + int found = 0; + size_t size = vma->vm_end - vma->vm_start; + + /* Is this a memory chunk provided by our driver ? */ + spin_lock(&fc->lock); + list_for_each_entry(p, &fc->blocks, n) { + if (((u64)p->dma_handle == ((u64)vma->vm_pgoff << PAGE_SHIFT)) && + (size <= p->size)) { + found = 1; + break; + } + } + spin_unlock(&fc->lock); + + if (!found) + return -EPERM; + + vma->vm_page_prot = phys_mem_access_prot(filp, vma->vm_pgoff, + size, + vma->vm_page_prot); + + vma->vm_ops = &mmap_mem_ops; + + /* Remap-pfn-range will mark the range VM_IO */ + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + +static struct file_operations memalloc_fops = { + .owner = THIS_MODULE, + .open = memalloc_open, + .release = memalloc_release, + .unlocked_ioctl = memalloc_ioctl, + .llseek = noop_llseek, + .mmap = memalloc_mmap, +}; + +static int memalloc_init(void) +{ + struct memalloc_drv *m = &memalloc_ing; + int ret; + + m->major = register_chrdev(0, "memalloc", &memalloc_fops); + if (m->major < 0) { + pr_err("failed to register character device\n"); + return m->major; + } + + /* create /dev/memalloc */ + m->class = class_create(THIS_MODULE, "memalloc-cls"); + if (IS_ERR(m->class)) { + ret = PTR_ERR(m->class); + goto err; + } + m->dev = device_create(m->class, NULL, MKDEV(m->major, 0), NULL, "memalloc"); + if (IS_ERR(m->dev)) { + ret = PTR_ERR(m->dev); + class_destroy(m->class); + goto err; + } + + m->dev->coherent_dma_mask = DMA_BIT_MASK(32); + dev_dbg(m->dev, "allocator with major = %d\n", m->major); + + return 0; +err: + unregister_chrdev(m->major, "memalloc"); + return ret; + +} +module_init(memalloc_init); + +static void memalloc_exit(void) +{ + struct memalloc_drv *m = &memalloc_ing; + + device_destroy(m->class, MKDEV(m->major, 0)); + class_destroy(m->class); + unregister_chrdev(m->major, "memalloc"); +} +module_exit(memalloc_exit); + +MODULE_AUTHOR("Hantro Products Oy"); +MODULE_DESCRIPTION("Memory allocator for VDEC"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.5"); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/memalloc.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/memalloc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Memalloc, encoder memory allocation driver (kernel module headers) + * + * Copyright (C) 2009 Hantro Products Oy. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef MEMALLOC_H +#define MEMALLOC_H + +#include <linux/ioctl.h> + +/* Use 'k' as magic number */ +#define MEMALLOC_IOC_MAGIC 'k' +/* + * S means "Set" through a ptr, + * T means "Tell" directly with the argument value + * G means "Get": reply by setting through a pointer + * Q means "Query": response is on the return value + * X means "eXchange": G and S atomically + * H means "sHift": T and Q atomically + */ +#define MEMALLOC_IOCXGETBUFFER _IOWR(MEMALLOC_IOC_MAGIC, 1, MemallocParams*) +#define MEMALLOC_IOCSFREEBUFFER _IOW(MEMALLOC_IOC_MAGIC, 2, unsigned long) + +/* + * ... more to come + * + * debugging tool + * #define MEMALLOC_IOCHARDRESET _IO(MEMALLOC_IOC_MAGIC, 15) + * #define MEMALLOC_IOC_MAXNR 15 + * + */ + +typedef struct { + unsigned busAddress; + unsigned size; +} MemallocParams; + +#endif /* MEMALLOC_H */ Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/pm.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:17 @ #include <linux/suspend.h> #include <linux/sched.h> #include <linux/proc_fs.h> +#include <linux/genalloc.h> #include <linux/interrupt.h> #include <linux/sysfs.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/clk/at91_pmc.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:32 @ #include <linux/atomic.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> +#include <asm/fncpy.h> +#include <asm/cacheflush.h> #include <mach/cpu.h> #include <mach/hardware.h> -#include "at91_aic.h" #include "generic.h" #include "pm.h" -#include "gpio.h" -static void (*at91_pm_standby)(void); +static struct { + unsigned long uhp_udp_mask; + int memctrl; + unsigned int ddrc_pid; + bool is_sama5d4; +} at91_pm_data; + +void __iomem *at91_ramc_base[2]; static int at91_pm_valid_state(suspend_state_t state) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:87 @ static int at91_pm_verify_clocks(void) scsr = at91_pmc_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ - if (cpu_is_at91rm9200()) { - if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { - pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; - } - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() - || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { - if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { - pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; - } + if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { + pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; } /* PCK0..PCK3 must be disabled, or configured to use clk32k */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:106 @ static int at91_pm_verify_clocks(void) } } + /* Drivers should have previously suspended USB PLL */ + if (at91_pmc_read(AT91_CKGR_UCKR) & AT91_PMC_UPLLEN) { + pr_err("AT91: PM - Suspend-to-RAM with USB PLL running\n"); + return 0; + } + + /* Drivers should have previously suspended PLL B */ + if (at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) { + pr_err("AT91: PM - Suspend-to-RAM with PLL B running\n"); + return 0; + } + return 1; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:137 @ int at91_suspend_entering_slow_clock(voi } EXPORT_SYMBOL(at91_suspend_entering_slow_clock); - -static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, +static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1, int memctrl); -#ifdef CONFIG_AT91_SLOW_CLOCK -extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, +extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1, int memctrl); -extern u32 at91_slow_clock_sz; -#endif +extern u32 at91_pm_suspend_in_sram_sz; -static int at91_pm_enter(suspend_state_t state) +static void at91_pm_suspend(suspend_state_t state) { - if (of_have_populated_dt()) - at91_pinctrl_gpio_suspend(); - else - at91_gpio_suspend(); + unsigned int pm_data = at91_pm_data.memctrl; - if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) { - at91_irq_suspend(); + pm_data |= (state == PM_SUSPEND_MEM) ? + AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0; - pr_debug("AT91: PM - wake mask %08x, pm state %d\n", - /* remember all the always-wake irqs */ - (at91_pmc_read(AT91_PMC_PCSR) - | (1 << AT91_ID_FIQ) - | (1 << AT91_ID_SYS) - | (at91_get_extern_irq())) - & at91_aic_read(AT91_AIC_IMR), - state); - } + pm_data |= AT91_PM_DDRC_PID(at91_pm_data.ddrc_pid); + pm_data |= at91_pm_data.is_sama5d4 ? + AT91_PM_IS_SAMA5D4(AT91_PM_SAMA5D4_BIT) : 0; + + flush_cache_all(); + outer_disable(); + + at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], + at91_ramc_base[1], pm_data); + + outer_resume(); +} + +static int at91_pm_enter(suspend_state_t state) +{ + at91_pinctrl_gpio_suspend(); switch (state) { + /* + * Suspend-to-RAM is like STANDBY plus slow clock mode, so + * drivers must suspend more deeply, the master clock switches + * to the clk32k and turns off the main oscillator + */ + case PM_SUSPEND_MEM: /* - * Suspend-to-RAM is like STANDBY plus slow clock mode, so - * drivers must suspend more deeply: only the master clock - * controller may be using the main oscillator. + * Ensure that clocks are in a valid state. */ - case PM_SUSPEND_MEM: - /* - * Ensure that clocks are in a valid state. - */ - if (!at91_pm_verify_clocks()) - goto error; - - /* - * Enter slow clock mode by switching over to clk32k and - * turning off the main oscillator; reverse on wakeup. - */ - if (slow_clock) { - int memctrl = AT91_MEMCTRL_SDRAMC; - - if (cpu_is_at91rm9200()) - memctrl = AT91_MEMCTRL_MC; - else if (cpu_is_at91sam9g45()) - memctrl = AT91_MEMCTRL_DDRSDR; -#ifdef CONFIG_AT91_SLOW_CLOCK - /* copy slow_clock handler to SRAM, and call it */ - memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); -#endif - slow_clock(at91_pmc_base, at91_ramc_base[0], - at91_ramc_base[1], memctrl); - break; - } else { - pr_info("AT91: PM - no slow clock mode enabled ...\n"); - /* FALLTHROUGH leaving master clock alone */ - } + if (!at91_pm_verify_clocks()) + goto error; - /* - * STANDBY mode has *all* drivers suspended; ignores irqs not - * marked as 'wakeup' event sources; and reduces DRAM power. - * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and - * nothing fancy done with main or cpu clocks. - */ - case PM_SUSPEND_STANDBY: - /* - * NOTE: the Wait-for-Interrupt instruction needs to be - * in icache so no SDRAM accesses are needed until the - * wakeup IRQ occurs and self-refresh is terminated. - * For ARM 926 based chips, this requirement is weaker - * as at91sam9 can access a RAM in self-refresh mode. - */ - if (at91_pm_standby) - at91_pm_standby(); - break; + at91_pm_suspend(state); - case PM_SUSPEND_ON: - cpu_do_idle(); - break; + break; - default: - pr_debug("AT91: PM - bogus suspend state %d\n", state); - goto error; + /* + * STANDBY mode has *all* drivers suspended; ignores irqs not + * marked as 'wakeup' event sources; and reduces DRAM power. + * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and + * nothing fancy done with main or cpu clocks. + */ + case PM_SUSPEND_STANDBY: + at91_pm_suspend(state); + break; + + case PM_SUSPEND_ON: + cpu_do_idle(); + break; + + default: + pr_debug("AT91: PM - bogus suspend state %d\n", state); + goto error; } - if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) - pr_debug("AT91: PM - wakeup %08x\n", - at91_aic_read(AT91_AIC_IPR) & - at91_aic_read(AT91_AIC_IMR)); - error: target_state = PM_SUSPEND_ON; - if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) - at91_irq_resume(); - - if (of_have_populated_dt()) - at91_pinctrl_gpio_resume(); - else - at91_gpio_resume(); + at91_pinctrl_gpio_resume(); return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:231 @ static struct platform_device at91_cpuid .name = "cpuidle-at91", }; -void at91_pm_set_standby(void (*at91_standby)(void)) +static void at91_pm_set_standby(void (*at91_standby)(void)) { - if (at91_standby) { + if (at91_standby) at91_cpuidle_device.dev.platform_data = at91_standby; - at91_pm_standby = at91_standby; +} + +static struct of_device_id ramc_ids[] = { + { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, + { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, + { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, + { /*sentinel*/ } +}; + +static void at91_dt_ramc(void) +{ + struct device_node *np; + const struct of_device_id *of_id; + int idx = 0; + const void *standby = NULL; + + for_each_matching_node_and_match(np, ramc_ids, &of_id) { + at91_ramc_base[idx] = of_iomap(np, 0); + if (!at91_ramc_base[idx]) + panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); + + if (!standby) + standby = of_id->data; + + idx++; } + + if (!idx) + panic(pr_fmt("unable to find compatible ram controller node in dtb\n")); + + if (!standby) { + pr_warn("ramc no standby function available\n"); + return; + } + + at91_pm_set_standby(standby); } -static int __init at91_pm_init(void) +static void __init at91_pm_sram_init(void) { -#ifdef CONFIG_AT91_SLOW_CLOCK - slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz); -#endif + struct gen_pool *sram_pool; + phys_addr_t sram_pbase; + unsigned long sram_base; + struct device_node *node; + struct platform_device *pdev = NULL; + + for_each_compatible_node(node, NULL, "mmio-sram") { + pdev = of_find_device_by_node(node); + if (pdev) { + of_node_put(node); + break; + } + } + + if (!pdev) { + pr_warn("%s: failed to find sram device!\n", __func__); + return; + } + + sram_pool = dev_get_gen_pool(&pdev->dev); + if (!sram_pool) { + pr_warn("%s: sram pool unavailable!\n", __func__); + return; + } + + sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz); + if (!sram_base) { + pr_warn("%s: unable to alloc ocram!\n", __func__); + return; + } + + sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); + at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase, + at91_pm_suspend_in_sram_sz, false); + if (!at91_suspend_sram_fn) { + pr_warn("SRAM: Could not map\n"); + return; + } - pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : "")); + /* Copy the pm suspend handler to SRAM */ + at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, + &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); +} + +static void __init at91_pm_init(void) +{ + at91_pm_sram_init(); - /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ - if (cpu_is_at91rm9200()) - at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); - if (at91_cpuidle_device.dev.platform_data) platform_device_register(&at91_cpuidle_device); - suspend_set_ops(&at91_pm_ops); + if (at91_suspend_sram_fn) + suspend_set_ops(&at91_pm_ops); + else + pr_info("AT91: PM not supported, due to no SRAM allocated\n"); +} + +void __init at91rm9200_pm_init(void) +{ + at91_dt_ramc(); - return 0; + /* + * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. + */ + at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); + + at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_MC; + + at91_pm_init(); +} + +void __init at91sam9260_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + return at91_pm_init(); +} + +void __init at91sam9g45_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; + return at91_pm_init(); +} + +void __init at91sam9x5_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; + return at91_pm_init(); +} + +void __init sam5d3_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; + at91_pm_data.ddrc_pid = SAMA5D3_ID_MPDDRC; + return at91_pm_init(); +} + +void __init sam5d4_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; + at91_pm_data.ddrc_pid = SAMA5D4_ID_MPDDRC; + at91_pm_data.is_sama5d4 = true; + return at91_pm_init(); } -arch_initcall(at91_pm_init); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/pm.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:17 @ #include <asm/proc-fns.h> #include <mach/at91_ramc.h> -#include <mach/at91rm9200_sdramc.h> -#ifdef CONFIG_PM -extern void at91_pm_set_standby(void (*at91_standby)(void)); -#else -static inline void at91_pm_set_standby(void (*at91_standby)(void)) { } -#endif +#define AT91_PM_MEMTYPE_MASK 0x0f + +#define AT91_PM_MODE_OFFSET 4 +#define AT91_PM_MODE_MASK 0x01 +#define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET) + +#define AT91_PM_SLOW_CLOCK 0x01 +#define AT91_PM_DDRC_PID_MASK 0xff +#define AT91_PM_DDRC_PID_OFFSET 8 +#define AT91_PM_DDRC_PID(x) (((x) & AT91_PM_DDRC_PID_MASK) << AT91_PM_DDRC_PID_OFFSET) + +#define AT91_PM_SAMA5D4_MASK 0x01 +#define AT91_PM_SAMA5D4_OFFSET 24 +#define AT91_PM_IS_SAMA5D4(x) (((x) & AT91_PM_SAMA5D4_MASK) << AT91_PM_SAMA5D4_OFFSET) +#define AT91_PM_SAMA5D4_BIT 0x01 + +#ifndef __ASSEMBLY__ /* * The AT91RM9200 goes into self-refresh mode with this command, and will * terminate self-refresh automatically on the next SDRAM access. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:127 @ static inline void at91sam9_sdram_standb } #endif +#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm_slowclock.S =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/pm_slowclock.S +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -/* - * arch/arm/mach-at91/pm_slow_clock.S - * - * Copyright (C) 2006 Savin Zlobec - * - * AT91SAM9 support: - * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee - * - * 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 <linux/linkage.h> -#include <linux/clk/at91_pmc.h> -#include <mach/hardware.h> -#include <mach/at91_ramc.h> - - -#ifdef CONFIG_SOC_AT91SAM9263 -/* - * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; - * handle those cases both here and in the Suspend-To-RAM support. - */ -#warning Assuming EB1 SDRAM controller is *NOT* used -#endif - -/* - * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master - * clock during suspend by adjusting its prescalar and divisor. - * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there - * are errata regarding adjusting the prescalar and divisor. - */ -#undef SLOWDOWN_MASTER_CLOCK - -#define MCKRDY_TIMEOUT 1000 -#define MOSCRDY_TIMEOUT 1000 -#define PLLALOCK_TIMEOUT 1000 -#define PLLBLOCK_TIMEOUT 1000 - -pmc .req r0 -sdramc .req r1 -ramc1 .req r2 -memctrl .req r3 -tmp1 .req r4 -tmp2 .req r5 - -/* - * Wait until master clock is ready (after switching master clock source) - */ - .macro wait_mckrdy - mov tmp2, #MCKRDY_TIMEOUT -1: sub tmp2, tmp2, #1 - cmp tmp2, #0 - beq 2f - ldr tmp1, [pmc, #AT91_PMC_SR] - tst tmp1, #AT91_PMC_MCKRDY - beq 1b -2: - .endm - -/* - * Wait until master oscillator has stabilized. - */ - .macro wait_moscrdy - mov tmp2, #MOSCRDY_TIMEOUT -1: sub tmp2, tmp2, #1 - cmp tmp2, #0 - beq 2f - ldr tmp1, [pmc, #AT91_PMC_SR] - tst tmp1, #AT91_PMC_MOSCS - beq 1b -2: - .endm - -/* - * Wait until PLLA has locked. - */ - .macro wait_pllalock - mov tmp2, #PLLALOCK_TIMEOUT -1: sub tmp2, tmp2, #1 - cmp tmp2, #0 - beq 2f - ldr tmp1, [pmc, #AT91_PMC_SR] - tst tmp1, #AT91_PMC_LOCKA - beq 1b -2: - .endm - -/* - * Wait until PLLB has locked. - */ - .macro wait_pllblock - mov tmp2, #PLLBLOCK_TIMEOUT -1: sub tmp2, tmp2, #1 - cmp tmp2, #0 - beq 2f - ldr tmp1, [pmc, #AT91_PMC_SR] - tst tmp1, #AT91_PMC_LOCKB - beq 1b -2: - .endm - - .text - -/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, - * void __iomem *ramc1, int memctrl) - */ -ENTRY(at91_slow_clock) - /* Save registers on stack */ - stmfd sp!, {r4 - r12, lr} - - /* - * Register usage: - * R0 = Base address of AT91_PMC - * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) - * R2 = Base address of second RAM Controller or 0 if not present - * R3 = Memory controller - * R4 = temporary register - * R5 = temporary register - */ - - /* Drain write buffer */ - mov tmp1, #0 - mcr p15, 0, tmp1, c7, c10, 4 - - cmp memctrl, #AT91_MEMCTRL_MC - bne ddr_sr_enable - - /* - * at91rm9200 Memory controller - */ - /* Put SDRAM in self-refresh mode */ - mov tmp1, #1 - str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] - b sdr_sr_done - - /* - * DDRSDR Memory controller - */ -ddr_sr_enable: - cmp memctrl, #AT91_MEMCTRL_DDRSDR - bne sdr_sr_enable - - /* prepare for DDRAM self-refresh mode */ - ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] - str tmp1, .saved_sam9_lpr - bic tmp1, #AT91_DDRSDRC_LPCB - orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH - - /* figure out if we use the second ram controller */ - cmp ramc1, #0 - ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] - strne tmp2, .saved_sam9_lpr1 - bicne tmp2, #AT91_DDRSDRC_LPCB - orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH - - /* Enable DDRAM self-refresh mode */ - str tmp1, [sdramc, #AT91_DDRSDRC_LPR] - strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] - - b sdr_sr_done - - /* - * SDRAMC Memory controller - */ -sdr_sr_enable: - /* Enable SDRAM self-refresh mode */ - ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] - str tmp1, .saved_sam9_lpr - - bic tmp1, #AT91_SDRAMC_LPCB - orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH - str tmp1, [sdramc, #AT91_SDRAMC_LPR] - -sdr_sr_done: - /* Save Master clock setting */ - ldr tmp1, [pmc, #AT91_PMC_MCKR] - str tmp1, .saved_mckr - - /* - * Set the Master clock source to slow clock - */ - bic tmp1, tmp1, #AT91_PMC_CSS - str tmp1, [pmc, #AT91_PMC_MCKR] - - wait_mckrdy - -#ifdef SLOWDOWN_MASTER_CLOCK - /* - * Set the Master Clock PRES and MDIV fields. - * - * See AT91RM9200 errata #27 and #28 for details. - */ - mov tmp1, #0 - str tmp1, [pmc, #AT91_PMC_MCKR] - - wait_mckrdy -#endif - - /* Save PLLA setting and disable it */ - ldr tmp1, [pmc, #AT91_CKGR_PLLAR] - str tmp1, .saved_pllar - - mov tmp1, #AT91_PMC_PLLCOUNT - orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ - str tmp1, [pmc, #AT91_CKGR_PLLAR] - - /* Save PLLB setting and disable it */ - ldr tmp1, [pmc, #AT91_CKGR_PLLBR] - str tmp1, .saved_pllbr - - mov tmp1, #AT91_PMC_PLLCOUNT - str tmp1, [pmc, #AT91_CKGR_PLLBR] - - /* Turn off the main oscillator */ - ldr tmp1, [pmc, #AT91_CKGR_MOR] - bic tmp1, tmp1, #AT91_PMC_MOSCEN - str tmp1, [pmc, #AT91_CKGR_MOR] - - /* Wait for interrupt */ - mcr p15, 0, tmp1, c7, c0, 4 - - /* Turn on the main oscillator */ - ldr tmp1, [pmc, #AT91_CKGR_MOR] - orr tmp1, tmp1, #AT91_PMC_MOSCEN - str tmp1, [pmc, #AT91_CKGR_MOR] - - wait_moscrdy - - /* Restore PLLB setting */ - ldr tmp1, .saved_pllbr - str tmp1, [pmc, #AT91_CKGR_PLLBR] - - tst tmp1, #(AT91_PMC_MUL & 0xff0000) - bne 1f - tst tmp1, #(AT91_PMC_MUL & ~0xff0000) - beq 2f -1: - wait_pllblock -2: - - /* Restore PLLA setting */ - ldr tmp1, .saved_pllar - str tmp1, [pmc, #AT91_CKGR_PLLAR] - - tst tmp1, #(AT91_PMC_MUL & 0xff0000) - bne 3f - tst tmp1, #(AT91_PMC_MUL & ~0xff0000) - beq 4f -3: - wait_pllalock -4: - -#ifdef SLOWDOWN_MASTER_CLOCK - /* - * First set PRES if it was not 0, - * than set CSS and MDIV fields. - * - * See AT91RM9200 errata #27 and #28 for details. - */ - ldr tmp1, .saved_mckr - tst tmp1, #AT91_PMC_PRES - beq 2f - and tmp1, tmp1, #AT91_PMC_PRES - str tmp1, [pmc, #AT91_PMC_MCKR] - - wait_mckrdy -#endif - - /* - * Restore master clock setting - */ -2: ldr tmp1, .saved_mckr - str tmp1, [pmc, #AT91_PMC_MCKR] - - wait_mckrdy - - /* - * at91rm9200 Memory controller - * Do nothing - self-refresh is automatically disabled. - */ - cmp memctrl, #AT91_MEMCTRL_MC - beq ram_restored - - /* - * DDRSDR Memory controller - */ - cmp memctrl, #AT91_MEMCTRL_DDRSDR - bne sdr_en_restore - /* Restore LPR on AT91 with DDRAM */ - ldr tmp1, .saved_sam9_lpr - str tmp1, [sdramc, #AT91_DDRSDRC_LPR] - - /* if we use the second ram controller */ - cmp ramc1, #0 - ldrne tmp2, .saved_sam9_lpr1 - strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] - - b ram_restored - - /* - * SDRAMC Memory controller - */ -sdr_en_restore: - /* Restore LPR on AT91 with SDRAM */ - ldr tmp1, .saved_sam9_lpr - str tmp1, [sdramc, #AT91_SDRAMC_LPR] - -ram_restored: - /* Restore registers, and return */ - ldmfd sp!, {r4 - r12, pc} - - -.saved_mckr: - .word 0 - -.saved_pllar: - .word 0 - -.saved_pllbr: - .word 0 - -.saved_sam9_lpr: - .word 0 - -.saved_sam9_lpr1: - .word 0 - -ENTRY(at91_slow_clock_sz) - .word .-at91_slow_clock Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm_suspend.S =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/pm_suspend.S @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * arch/arm/mach-at91/pm_suspend.S + * + * Copyright (C) 2006 Savin Zlobec + * + * AT91SAM9 support: + * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee + * + * 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 <linux/linkage.h> +#include <linux/clk/at91_pmc.h> +#include <mach/hardware.h> +#include <mach/at91_ramc.h> +#include "pm.h" + +#define SRAMC_SELF_FRESH_ACTIVE 0x01 +#define SRAMC_SELF_FRESH_EXIT 0x00 + +#define DDR_CLOCK_ENABLE 0x01 +#define DDR_CLOCK_DISABLE 0x00 + +pmc .req r0 +tmp1 .req r4 +tmp2 .req r5 + +/* + * Wait until master clock is ready (after switching master clock source) + */ + .macro wait_mckrdy +1: ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MCKRDY + beq 1b + .endm + +/* + * Wait until master oscillator has stabilized. + */ + .macro wait_moscrdy +1: ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MOSCS + beq 1b + .endm + +/* + * Wait until PLLA has locked. + */ + .macro wait_pllalock +1: ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKA + beq 1b + .endm + +/* + * Put the processor to enter the idle state + */ + .macro at91_cpu_idle + +#if defined(CONFIG_CPU_V7) + mov tmp1, #AT91_PMC_PCK + str tmp1, [pmc, #AT91_PMC_SCDR] + + dsb + + wfi @ Wait For Interrupt +#else + mcr p15, 0, tmp1, c7, c0, 4 +#endif + + .endm + + .text + + .arm + +/* + * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc, + * void __iomem *ramc1, int memctrl) + * @input param: + * @r0: base address of AT91_PMC + * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS) + * @r2: base address of second SDRAM Controller or 0 if not present + * @r3: pm information + */ +ENTRY(at91_pm_suspend_in_sram) + /* Save registers on stack */ + stmfd sp!, {r4 - r12, lr} + + /* Drain write buffer */ + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + + str r0, .pmc_base + str r1, .sramc_base + str r2, .sramc1_base + + and r0, r3, #AT91_PM_MEMTYPE_MASK + str r0, .memtype + + lsr r0, r3, #AT91_PM_MODE_OFFSET + and r0, r0, #AT91_PM_MODE_MASK + str r0, .pm_mode + + lsr r0, r3, #AT91_PM_DDRC_PID_OFFSET + and r0, r0, #AT91_PM_DDRC_PID_MASK + str r0, .ddrc_pid + + lsr r0, r3, #AT91_PM_SAMA5D4_MASK + and r0, r0, #AT91_PM_SAMA5D4_OFFSET + str r0, .sama5d4_bit + + /* Active the self-refresh mode */ + mov r0, #SRAMC_SELF_FRESH_ACTIVE + bl at91_sramc_self_refresh + + /* If the cpu isn't sama5d4, disable the ddr clock here */ + ldr r0, .sama5d4_bit + tst r0, #AT91_PM_SAMA5D4_BIT + bne skip_ddr_clock + + /* Disable DDR clock */ + mov r0, #DDR_CLOCK_DISABLE + bl at91_ddr_clock + +skip_ddr_clock: + ldr r0, .pm_mode + tst r0, #AT91_PM_SLOW_CLOCK + beq skip_disable_main_clock + + ldr pmc, .pmc_base + + /* Save Master clock setting */ + ldr tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, .saved_mckr + + /* + * Set the Master clock source to slow clock + */ + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, #AT91_PMC_MCKR] + + wait_mckrdy + + /* Save PLLA setting and disable it */ + ldr tmp1, [pmc, #AT91_CKGR_PLLAR] + str tmp1, .saved_pllar + + mov tmp1, #AT91_PMC_PLLCOUNT + orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ + str tmp1, [pmc, #AT91_CKGR_PLLAR] + + /* Turn off the main oscillator */ + ldr tmp1, [pmc, #AT91_CKGR_MOR] + bic tmp1, tmp1, #AT91_PMC_MOSCEN + orr tmp1, tmp1, #AT91_PMC_KEY + str tmp1, [pmc, #AT91_CKGR_MOR] + + /* If the cpu is the sama5d4, disable the ddr clock here */ + ldr r0, .sama5d4_bit + tst r0, #AT91_PM_SAMA5D4_BIT + beq skip_disable_main_clock + + /* Disable DDR clock */ + mov r0, #DDR_CLOCK_DISABLE + bl at91_ddr_clock + +skip_disable_main_clock: + ldr pmc, .pmc_base + + /* Wait for interrupt */ + at91_cpu_idle + + ldr r0, .pm_mode + tst r0, #AT91_PM_SLOW_CLOCK + beq skip_enable_main_clock + + ldr pmc, .pmc_base + + /* Turn on the main oscillator */ + ldr tmp1, [pmc, #AT91_CKGR_MOR] + orr tmp1, tmp1, #AT91_PMC_MOSCEN + orr tmp1, tmp1, #AT91_PMC_KEY + str tmp1, [pmc, #AT91_CKGR_MOR] + + wait_moscrdy + + /* Restore PLLA setting */ + ldr tmp1, .saved_pllar + str tmp1, [pmc, #AT91_CKGR_PLLAR] + + tst tmp1, #(AT91_PMC_MUL & 0xff0000) + bne 3f + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) + beq 4f +3: + wait_pllalock +4: + + /* + * Restore master clock setting + */ + ldr tmp1, .saved_mckr + str tmp1, [pmc, #AT91_PMC_MCKR] + + wait_mckrdy + +skip_enable_main_clock: + /* Enable DDR clock */ + mov r0, #DDR_CLOCK_ENABLE + bl at91_ddr_clock + + /* Exit the self-refresh mode */ + mov r0, #SRAMC_SELF_FRESH_EXIT + bl at91_sramc_self_refresh + + /* Restore registers, and return */ + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_pm_suspend_in_sram) + +/* + * void at91_sramc_self_refresh(unsigned int is_active) + * + * @input param: + * @r0: 1 - active self-refresh mode + * 0 - exit self-refresh mode + * register usage: + * @r1: memory type + * @r2: base address of the sram controller + */ + +ENTRY(at91_sramc_self_refresh) + ldr r1, .memtype + ldr r2, .sramc_base + + cmp r1, #AT91_MEMCTRL_MC + bne ddrc_sf + + /* + * at91rm9200 Memory controller + */ + + /* + * For exiting the self-refresh mode, do nothing, + * automatically exit the self-refresh mode. + */ + tst r0, #SRAMC_SELF_FRESH_ACTIVE + beq exit_sramc_sf + + /* Active SDRAM self-refresh mode */ + mov r3, #1 + str r3, [r2, #AT91RM9200_SDRAMC_SRR] + b exit_sramc_sf + +ddrc_sf: + cmp r1, #AT91_MEMCTRL_DDRSDR + bne sdramc_sf + + /* + * DDR Memory controller + */ + tst r0, #SRAMC_SELF_FRESH_ACTIVE + beq ddrc_exit_sf + + /* LPDDR1 --> force DDR2 mode during self-refresh */ + ldr r3, [r2, #AT91_DDRSDRC_MDR] + str r3, .saved_sam9_mdr + bic r3, r3, #~AT91_DDRSDRC_MD + cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR + ldreq r3, [r2, #AT91_DDRSDRC_MDR] + biceq r3, r3, #AT91_DDRSDRC_MD + orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 + streq r3, [r2, #AT91_DDRSDRC_MDR] + + /* Active DDRC self-refresh mode */ + ldr r3, [r2, #AT91_DDRSDRC_LPR] + str r3, .saved_sam9_lpr + bic r3, r3, #AT91_DDRSDRC_LPCB + orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + str r3, [r2, #AT91_DDRSDRC_LPR] + + /* If using the 2nd ddr controller */ + ldr r2, .sramc1_base + cmp r2, #0 + beq no_2nd_ddrc + + ldr r3, [r2, #AT91_DDRSDRC_MDR] + str r3, .saved_sam9_mdr1 + bic r3, r3, #~AT91_DDRSDRC_MD + cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR + ldreq r3, [r2, #AT91_DDRSDRC_MDR] + biceq r3, r3, #AT91_DDRSDRC_MD + orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 + streq r3, [r2, #AT91_DDRSDRC_MDR] + + ldr r3, [r2, #AT91_DDRSDRC_LPR] + str r3, .saved_sam9_lpr1 + bic r3, r3, #AT91_DDRSDRC_LPCB + orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + + /* Active DDRC self-refresh mode */ + str r3, [r2, #AT91_DDRSDRC_LPR] +no_2nd_ddrc: + b exit_sramc_sf + +ddrc_exit_sf: + /* Restore MDR in case of LPDDR1 */ + ldr r3, .saved_sam9_mdr + str r3, [r2, #AT91_DDRSDRC_MDR] + /* Restore LPR on AT91 with DDRAM */ + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_DDRSDRC_LPR] + + /* If using the 2nd ddr controller */ + ldr r2, .sramc1_base + cmp r2, #0 + ldrne r3, .saved_sam9_mdr1 + strne r3, [r2, #AT91_DDRSDRC_MDR] + ldrne r3, .saved_sam9_lpr1 + strne r3, [r2, #AT91_DDRSDRC_LPR] + + b exit_sramc_sf + + /* + * SDRAMC Memory controller + */ +sdramc_sf: + tst r0, #SRAMC_SELF_FRESH_ACTIVE + beq sdramc_exit_sf + + /* Active SDRAMC self-refresh mode */ + ldr r3, [r2, #AT91_SDRAMC_LPR] + str r3, .saved_sam9_lpr + + bic r3, r3, #AT91_SDRAMC_LPCB + orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH + str r3, [r2, #AT91_SDRAMC_LPR] + +sdramc_exit_sf: + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_SDRAMC_LPR] + +exit_sramc_sf: + mov pc, lr +ENDPROC(at91_sramc_self_refresh) + +/* + * void at91_ddr_clock(unsigned char is_enable) + * + * @input param + * @r0: 0x01 - enable DDR clock + * 0x00 - disable DDR clock + * register usage: + * @r1: ddrc peripheral id + * @r2: base address of the pmc + */ +ENTRY(at91_ddr_clock) + ldr r1, .ddrc_pid + ldr r2, .pmc_base + + /* DDRC peripheral clock */ + cmp r1, #0 + beq ddr_sys_clk + + and r1, r1, #AT91_PMC_PCR_PID + orr r1, r1, #AT91_PMC_PCR_CMD + + tst r0, #DDR_CLOCK_ENABLE + beq ddrc_clk + orr r1, r1, #AT91_PMC_PCR_EN + +ddrc_clk: + str r1, [r2, #AT91_PMC_PCR] + +ddr_sys_clk: + /* DDR system clock */ + mov r3, #AT91_PMC_SYS_DDR + + tst r0, #DDR_CLOCK_ENABLE + beq disable_sys_clk + + str r3, [r2, #AT91_PMC_SCER] + b exit_ddr_clock + +disable_sys_clk: + str r3, [r2, #AT91_PMC_SCDR] + +exit_ddr_clock: + mov pc, lr +ENDPROC(at91_ddr_clock) + +.pmc_base: + .word 0 +.sramc_base: + .word 0 +.sramc1_base: + .word 0 +.memtype: + .word 0 +.pm_mode: + .word 0 +.ddrc_pid: + .word 0 +.sama5d4_bit: + .word 0 +.saved_mckr: + .word 0 +.saved_pllar: + .word 0 +.saved_sam9_lpr: + .word 0 +.saved_sam9_lpr1: + .word 0 +.saved_sam9_mdr: + .word 0 +.saved_sam9_mdr1: + .word 0 + +ENTRY(at91_pm_suspend_in_sram_sz) + .word .-at91_pm_suspend_in_sram Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/sama5d3.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/sama5d3.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/sama5d3.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ #include "sam9_smc.h" /* -------------------------------------------------------------------- - * AT91SAM9x5 processor initialization + * SAMA5D3 processor initialization * -------------------------------------------------------------------- */ -static void __init sama5d3_map_io(void) -{ - at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE); -} - static void __init sama5d3_initialize(void) { at91_sysirq_mask_rtc(SAMA5D3_BASE_RTC); } AT91_SOC_START(sama5d3) - .map_io = sama5d3_map_io, .init = sama5d3_initialize, AT91_SOC_END Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/sama5d4.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/sama5d4.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/sama5d4.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:59 @ static struct map_desc at91_io_desc[] __ static void __init sama5d4_map_io(void) { iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc)); - at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE); } AT91_SOC_START(sama5d4) Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/setup.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/setup.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/setup.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:45 @ void __init at91rm9200_set_type(int type at91_get_soc_subtype(&at91_soc_initdata)); } -void __init at91_init_irq_default(void) -{ - at91_init_interrupts(at91_boot_soc.default_irq_priority); -} - -void __init at91_init_interrupts(unsigned int *priority) -{ - /* Initialize the AIC interrupt controller */ - if (IS_ENABLED(CONFIG_OLD_IRQ_AT91)) - at91_aic_init(priority, at91_boot_soc.extern_irq); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} - -void __iomem *at91_ramc_base[2]; -EXPORT_SYMBOL_GPL(at91_ramc_base); - -void __init at91_ioremap_ramc(int id, u32 addr, u32 size) -{ - if (id < 0 || id > 1) { - pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id); - BUG(); - } - at91_ramc_base[id] = ioremap(addr, size); - if (!at91_ramc_base[id]) - panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr); -} - -static struct map_desc sram_desc[2] __initdata; - -void __init at91_init_sram(int bank, unsigned long base, unsigned int length) -{ - struct map_desc *desc = &sram_desc[bank]; - - desc->virtual = (unsigned long)AT91_IO_VIRT_BASE - length; - if (bank > 0) - desc->virtual -= sram_desc[bank - 1].length; - - desc->pfn = __phys_to_pfn(base); - desc->length = length; - desc->type = MT_MEMORY_RWX_NONCACHED; - - pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n", - base, length, desc->virtual); - - iotable_init(desc, 1); -} - static struct map_desc at91_io_desc __initdata __maybe_unused = { .virtual = (unsigned long)AT91_VA_BASE_SYS, .pfn = __phys_to_pfn(AT91_BASE_SYS), @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:372 @ void __init at91_ioremap_matrix(u32 base panic(pr_fmt("Impossible to ioremap at91_matrix_base\n")); } -#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40) -static struct of_device_id ramc_ids[] = { - { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, - { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, - { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, - { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, - { /*sentinel*/ } -}; - -static void at91_dt_ramc(void) -{ - struct device_node *np; - const struct of_device_id *of_id; - int idx = 0; - const void *standby = NULL; - - for_each_matching_node_and_match(np, ramc_ids, &of_id) { - at91_ramc_base[idx] = of_iomap(np, 0); - if (!at91_ramc_base[idx]) - panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); - - if (!standby) - standby = of_id->data; - - idx++; - } - - if (!idx) - panic(pr_fmt("unable to find compatible ram controller node in dtb\n")); - - if (!standby) { - pr_warn("ramc no standby function available\n"); - return; - } - - at91_pm_set_standby(standby); -} - void __init at91rm9200_dt_initialize(void) { - at91_dt_ramc(); - - /* Init clock subsystem */ - at91_dt_clock_init(); - - /* Register the processor-specific clocks */ - if (at91_boot_soc.register_clocks) - at91_boot_soc.register_clocks(); - at91_boot_soc.init(); } void __init at91_dt_initialize(void) { - at91_dt_ramc(); - - /* Init clock subsystem */ - at91_dt_clock_init(); - - /* Register the processor-specific clocks */ - if (at91_boot_soc.register_clocks) - at91_boot_soc.register_clocks(); - if (at91_boot_soc.init) at91_boot_soc.init(); } -#endif - -void __init at91_initialize(unsigned long main_clock) -{ - at91_boot_soc.ioremap_registers(); - - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91_boot_soc.register_clocks(); - - at91_boot_soc.init(); - - pinctrl_provide_dummies(); -} - -void __init at91_register_devices(void) -{ - at91_boot_soc.register_devices(); -} - -void __init at91_init_time(void) -{ - at91_boot_soc.init_time(); -} Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/soc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/soc.h +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/soc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:9 @ struct at91_init_soc { int builtin; - u32 extern_irq; - unsigned int *default_irq_priority; void (*map_io)(void); - void (*ioremap_registers)(void); - void (*register_clocks)(void); - void (*register_devices)(void); void (*init)(void); - void (*init_time)(void); }; extern struct at91_init_soc at91_boot_soc; Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/stamp9g20.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-at91/stamp9g20.h +++ /dev/null @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ -#ifndef __MACH_STAMP9G20_H -#define __MACH_STAMP9G20_H - -void stamp9g20_init_early(void); -void stamp9g20_board_init(void); - -#endif Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/vdec_g1.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-at91/vdec_g1.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * On2/Hantro G1 decoder/pp driver. Single core version. + * + * Copyright (C) 2009 Hantro Products Oy. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/miscdevice.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include <linux/sched.h> + +#include "hx170dec.h" +#include "at91_vdec.h" + +#define VDEC_MAX_CORES 1 /* number of cores of the hardware IP */ +#define VDEC_NUM_REGS_DEC 60 /* number of registers of the Decoder part */ +#define VDEC_NUM_REGS_PP 41 /* number of registers of the Post Processor part */ +#define VDEC_DEC_FIRST_REG 0 /* first register (0-based) index */ +#define VDEC_DEC_LAST_REG 59 /* last register (0-based) index */ +#define VDEC_PP_FIRST_REG 60 +#define VDEC_PP_LAST_REG 100 + +struct vdec_device { + void __iomem *mmio_base; + struct clk *clk; + struct device *dev; + int irq; + int num_cores; + unsigned long iobaseaddr; + unsigned long iosize; + wait_queue_head_t dec_wq; + wait_queue_head_t pp_wq; + bool dec_irq_done; + bool pp_irq_done; + struct semaphore dec_sem; + struct semaphore pp_sem; + struct file *dec_owner; + struct file *pp_owner; + u32 regs[VDEC_NUM_REGS_DEC + VDEC_NUM_REGS_PP]; +}; +static struct vdec_device *vdec6731_global; + +static inline void vdec_writel(const struct vdec_device *p, unsigned offset, u32 val) +{ + writel(val, p->mmio_base + offset); +} + +static inline u32 vdec_readl(const struct vdec_device *p, unsigned offset) +{ + return readl(p->mmio_base + offset); +} + +/** + * Write a range of registers. First register is assumed to be + * "Interrupt Register" and will be written last. + */ +static int vdec_regs_write(struct vdec_device *p, int begin, int end, + const struct core_desc *core) +{ + int i; + + if (copy_from_user(&p->regs[begin], core->regs, (end - begin + 1) * 4)) + { + dev_err(p->dev, "%s: copy_from_user failed\n", __func__); + return -EFAULT; + } + + for (i = end; i >= begin; i--) + vdec_writel(p, 4 * i, p->regs[i]); + + return 0; +} + +/** + * Read a range of registers [begin..end] + */ +static int vdec_regs_read(struct vdec_device *p, int begin, int end, + const struct core_desc *core) +{ + int i; + + for (i = end; i >= begin; i--) + p->regs[i] = vdec_readl(p, 4 * i); + + if (copy_to_user(core->regs, &p->regs[begin], (end - begin + 1) * 4)) + { + dev_err(p->dev, "%s: copy_to_user failed\n", __func__); + return -EFAULT; + } + + return 0; +} + +/** + * Misc driver related + */ + +static int vdec_misc_open(struct inode *inode, struct file *filp) +{ + struct vdec_device *p = vdec6731_global; + filp->private_data = p; + + dev_dbg(p->dev, "open\n"); + clk_prepare_enable(p->clk); + return 0; +} + +static int vdec_misc_release(struct inode *inode, struct file *filp) +{ + struct vdec_device *p = filp->private_data; + + if (p->dec_owner == filp) { + p->dec_irq_done = false; + init_waitqueue_head(&p->dec_wq); + sema_init(&p->dec_sem, VDEC_MAX_CORES); + p->dec_owner = NULL; + } + + if (p->pp_owner == filp) { + p->pp_irq_done = false; + init_waitqueue_head(&p->pp_wq); + sema_init(&p->pp_sem, 1); + p->pp_owner = NULL; + } + + clk_disable_unprepare(p->clk); + dev_dbg(p->dev, "release\n"); + return 0; +} + +static long vdec_misc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int ret = 0; + void __user *argp = (void __user *)arg; + struct vdec_device *p = vdec6731_global; + struct core_desc core; + u32 reg; + + switch (cmd) { + case HX170DEC_IOX_ASIC_ID: + reg = vdec_readl(p, VDEC_IDR); + if (copy_to_user(argp, ®, sizeof(u32))) + ret = -EFAULT; + break; + + case HX170DEC_IOC_MC_OFFSETS: + case HX170DEC_IOCGHWOFFSET: + if (copy_to_user(argp, &p->iobaseaddr, sizeof(p->iobaseaddr))) + ret = -EFAULT; + break; + case HX170DEC_IOCGHWIOSIZE: /* in bytes */ + if (copy_to_user(argp, &p->iosize, sizeof(p->iosize))) + ret = -EFAULT; + break; + case HX170DEC_IOC_MC_CORES: + if (copy_to_user(argp, &p->num_cores, sizeof(p->num_cores))) + ret = -EFAULT; + break; + + case HX170DEC_IOCS_DEC_PUSH_REG: + if (copy_from_user(&core, (void *)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (dec push reg) failed\n"); + ret = -EFAULT; + } else { + /* Skip VDEC_IDR (ID Register, ro) */ + core.regs++; // core.size -= 4; + ret = vdec_regs_write(p, VDEC_DEC_FIRST_REG + 1, VDEC_DEC_LAST_REG, &core); + } + break; + case HX170DEC_IOCS_PP_PUSH_REG: + if (copy_from_user(&core, (void *)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (pp push reg) failed\n"); + ret = -EFAULT; + } else { + /* Don't consider the 5 lastest registers (ro or unused) */ + ret = vdec_regs_write(p, VDEC_PP_FIRST_REG, VDEC_PP_LAST_REG - 5, &core); + } + break; + + case HX170DEC_IOCS_DEC_PULL_REG: + if (copy_from_user(&core, (void *)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (dec pull reg) failed\n"); + ret = -EFAULT; + } else { + ret = vdec_regs_read(p, VDEC_DEC_FIRST_REG, VDEC_DEC_LAST_REG, &core); + } + break; + + case HX170DEC_IOCS_PP_PULL_REG: + if (copy_from_user(&core, (void*)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (pp pull reg) failed\n"); + ret = -EFAULT; + } else { + ret = vdec_regs_read(p, VDEC_PP_FIRST_REG, VDEC_PP_LAST_REG, &core); + } + break; + + case HX170DEC_IOCX_DEC_WAIT: + if (copy_from_user(&core, (void *)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (dec wait) failed\n"); + ret = -EFAULT; + } else { + ret = wait_event_interruptible(p->dec_wq, p->dec_irq_done); + p->dec_irq_done = false; + if (unlikely(ret != 0)) { + dev_err(p->dev, "wait_event_interruptible dec error %d\n", ret); + } else { + /* Update dec registers */ + ret = vdec_regs_read(p, VDEC_DEC_FIRST_REG, VDEC_DEC_LAST_REG, &core); + } + } + break; + case HX170DEC_IOCX_PP_WAIT: + if (copy_from_user(&core, (void *)arg, sizeof(struct core_desc))) { + dev_err(p->dev, "copy_from_user (pp wait) failed\n"); + ret = -EFAULT; + } else { + ret = wait_event_interruptible(p->pp_wq, p->pp_irq_done); + p->pp_irq_done = false; + if (unlikely(ret != 0)) { + dev_err(p->dev, "wait_event_interruptible pp error %d\n", ret); + } else { + /* Update pp registers */ + ret = vdec_regs_read(p, VDEC_PP_FIRST_REG, VDEC_PP_LAST_REG, &core); + } + } + break; + + case HX170DEC_IOCH_DEC_RESERVE: + if (likely(down_interruptible(&p->dec_sem) == 0)) { + p->dec_owner = filp; + ret = 0; /* core id */ + dev_dbg(p->dev, "down dec_sem (core id %d)\n", ret); + } else { + dev_err(p->dev, "down_interruptible dec error\n"); + ret = -ERESTARTSYS; + } + break; + case HX170DEC_IOCT_DEC_RELEASE: + dev_dbg(p->dev, "up dec_sem\n"); + p->dec_owner = NULL; + up(&p->dec_sem); + break; + + case HX170DEC_IOCQ_PP_RESERVE: + if (likely(down_interruptible(&p->pp_sem) == 0)) { + p->pp_owner = filp; + ret = 0; /* core id */ + dev_dbg(p->dev, "down pp_sem (core id %d)\n", ret); + } else { + dev_err(p->dev, "down_interruptible pp error\n"); + ret = -ERESTARTSYS; + } + break; + case HX170DEC_IOCT_PP_RELEASE: + dev_dbg(p->dev, "up pp_sem\n"); + p->pp_owner = NULL; + up(&p->pp_sem); + break; + + default: + dev_warn(p->dev, "unknown ioctl %x\n", cmd); + ret = -EINVAL; + } + return ret; +} + +const struct file_operations vdec_misc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = vdec_misc_open, + .release = vdec_misc_release, + .unlocked_ioctl = vdec_misc_ioctl, +}; + +static struct miscdevice vdec_misc_device = { + MISC_DYNAMIC_MINOR, + "vdec", + &vdec_misc_fops +}; + +/* + * Platform driver related + */ + +/* Should we use spin_lock_irqsave here? */ +static irqreturn_t vdec_isr(int irq, void *dev_id) +{ + struct vdec_device *p = dev_id; + u32 irq_status_dec, irq_status_pp; + int handled = 0; + + /* interrupt status register read */ + irq_status_dec = vdec_readl(p, VDEC_DIR); + if (irq_status_dec & VDEC_DIR_ISET) { + /* Clear IRQ */ + vdec_writel(p, VDEC_DIR, irq_status_dec & ~VDEC_DIR_ISET); + + p->dec_irq_done = true; + wake_up_interruptible(&p->dec_wq); + handled++; + } + + irq_status_pp = vdec_readl(p, VDEC_PPIR); + if (irq_status_pp & VDEC_PPIR_ISET) { + /* Clear IRQ */ + vdec_writel(p, VDEC_PPIR, irq_status_pp & ~VDEC_PPIR_ISET); + + p->pp_irq_done = true; + wake_up_interruptible(&p->pp_wq); + handled++; + } + + if (handled == 0) { + dev_warn(p->dev, "Spurious IRQ (DIR=%08x PPIR=%08x)\n", \ + irq_status_dec, irq_status_pp); + return IRQ_NONE; + } + + return IRQ_HANDLED; +} + +static int __init vdec_probe(struct platform_device *pdev) +{ + struct vdec_device *p; + struct resource *res; + int ret; + u32 hwid; + + /* Allocate private data */ + p = devm_kzalloc(&pdev->dev, sizeof(struct vdec_device), GFP_KERNEL); + if (!p) { + dev_dbg(&pdev->dev, "out of memory\n"); + return -ENOMEM; + } + + p->dev = &pdev->dev; + platform_set_drvdata(pdev, p); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + p->mmio_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(p->mmio_base)) + return PTR_ERR(p->mmio_base); + + p->clk = devm_clk_get(&pdev->dev, "vdec_clk"); + if (IS_ERR(p->clk)) { + dev_err(&pdev->dev, "no vdec_clk clock defined\n"); + return -ENXIO; + } + + p->irq = platform_get_irq(pdev, 0); + if (!p->irq) { + dev_err(&pdev->dev, "could not get irq\n"); + return -ENXIO; + } + + ret = devm_request_irq(&pdev->dev, p->irq, vdec_isr, + 0, pdev->name, p); + if (ret) { + dev_err(&pdev->dev, "unable to request VDEC irq\n"); + return ret; + } + + /* Register the miscdevice */ + ret = misc_register(&vdec_misc_device); + if (ret) { + dev_err(&pdev->dev, "unable to register miscdevice\n"); + return ret; + } + + p->num_cores = VDEC_MAX_CORES; + p->iosize = resource_size(res); + p->iobaseaddr = res->start; + vdec6731_global = p; + + p->dec_irq_done = false; + p->pp_irq_done = false; + p->dec_owner = NULL; + p->pp_owner = NULL; + init_waitqueue_head(&p->dec_wq); + init_waitqueue_head(&p->pp_wq); + sema_init(&p->dec_sem, VDEC_MAX_CORES); + sema_init(&p->pp_sem, 1); + + ret = clk_prepare_enable(p->clk); + if (ret) { + dev_err(&pdev->dev, "unable to prepare and enable clock\n"); + misc_deregister(&vdec_misc_device); + return ret; + } + + dev_info(&pdev->dev, "VDEC controller at 0x%p, irq = %d, misc_minor = %d\n", + p->mmio_base, p->irq, vdec_misc_device.minor); + + /* Reset Asic (just in case..) */ + vdec_writel(p, VDEC_DIR, VDEC_DIR_ID | VDEC_DIR_ABORT); + vdec_writel(p, VDEC_PPIR, VDEC_PPIR_ID); + + hwid = vdec_readl(p, VDEC_IDR); + clk_disable_unprepare(p->clk); + + dev_warn(&pdev->dev, "Product ID: %#x (revision %d.%d.%d)\n", \ + (hwid & VDEC_IDR_PROD_ID) >> 16, + (hwid & VDEC_IDR_MAJOR_VER) >> 12, + (hwid & VDEC_IDR_MINOR_VER) >> 4, + (hwid & VDEC_IDR_BUILD_VER)); + return 0; +} + +static int __exit vdec_remove(struct platform_device *pdev) +{ + platform_set_drvdata(pdev, NULL); + misc_deregister(&vdec_misc_device); + return 0; +} + +static const struct of_device_id vdec_of_match[] = { + { .compatible = "on2,g1", .data = NULL }, + {}, +}; +MODULE_DEVICE_TABLE(of, vdec_of_match); + +static struct platform_driver vdec_of_driver = { + .driver = { + .name = "atmel-vdec", + .owner = THIS_MODULE, + .of_match_table = vdec_of_match, + }, + .remove = vdec_remove, +}; + +module_platform_driver_probe(vdec_of_driver, vdec_probe); + +MODULE_AUTHOR("Hantro Products Oy"); +MODULE_DESCRIPTION("G1 decoder/pp driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.4"); +MODULE_ALIAS("platform:vdec"); Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/board-dm355-evm.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-davinci/board-dm355-evm.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/board-dm355-evm.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:297 @ static struct vpbe_output dm355evm_vpbe_ .default_mode = "ntsc", .num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing), .modes = dm355evm_enc_preset_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, }; Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/board-dm365-evm.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-davinci/board-dm365-evm.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/board-dm365-evm.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:488 @ static struct vpbe_output dm365evm_vpbe_ .default_mode = "ntsc", .num_modes = ARRAY_SIZE(dm365evm_enc_std_timing), .modes = dm365evm_enc_std_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, { .output = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:501 @ static struct vpbe_output dm365evm_vpbe_ .default_mode = "480p59_94", .num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing), .modes = dm365evm_enc_preset_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, }; Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/dm355.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-davinci/dm355.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/dm355.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:788 @ static struct resource dm355_v4l2_disp_r }, }; -static int dm355_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, - int field) +static int dm355_vpbe_setup_pinmux(u32 if_type, int field) { switch (if_type) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: davinci_cfg_reg(DM355_VOUT_FIELD_G70); break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: if (field) davinci_cfg_reg(DM355_VOUT_FIELD); else Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/dm365.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-davinci/dm365.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-davinci/dm365.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1309 @ static struct resource dm365_v4l2_disp_r }, }; -static int dm365_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, - int field) +static int dm365_vpbe_setup_pinmux(u32 if_type, int field) { switch (if_type) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: davinci_cfg_reg(DM365_VOUT_FIELD_G81); davinci_cfg_reg(DM365_VOUT_COUTL_EN); davinci_cfg_reg(DM365_VOUT_COUTH_EN); break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: if (field) davinci_cfg_reg(DM365_VOUT_FIELD); else Index: linux-3.18.13-rt10-r7s4/arch/arm/mach-shmobile/board-mackerel.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/arm/mach-shmobile/board-mackerel.c +++ linux-3.18.13-rt10-r7s4/arch/arm/mach-shmobile/board-mackerel.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1156 @ static struct soc_camera_platform_info c .format_name = "UYVY", .format_depth = 16, .format = { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_SMPTE170M, .field = V4L2_FIELD_NONE, .width = 640, Index: linux-3.18.13-rt10-r7s4/arch/sh/boards/mach-ap325rxa/setup.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/arch/sh/boards/mach-ap325rxa/setup.c +++ linux-3.18.13-rt10-r7s4/arch/sh/boards/mach-ap325rxa/setup.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:341 @ static struct soc_camera_platform_info c .format_name = "UYVY", .format_depth = 16, .format = { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_SMPTE170M, .field = V4L2_FIELD_NONE, .width = 640, Index: linux-3.18.13-rt10-r7s4/Documentation/clk.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/clk.txt +++ linux-3.18.13-rt10-r7s4/Documentation/clk.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:77 @ the operations defined in clk.h: long (*determine_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_clk); + struct clk_hw **best_parent_clk); int (*set_parent)(struct clk_hw *hw, u8 index); u8 (*get_parent)(struct clk_hw *hw); int (*set_rate)(struct clk_hw *hw, Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/dma/atmel-xdma.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/dma/atmel-xdma.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +* Atmel Extensible Direct Memory Access Controller (XDMAC) + +* XDMA Controller +Required properties: +- compatible: Should be "atmel,<chip>-dma". + <chip> compatible description: + - sama5d4: first SoC adding the XDMAC +- reg: Should contain DMA registers location and length. +- interrupts: Should contain DMA interrupt. +- #dma-cells: Must be <1>, used to represent the number of integer cells in +the dmas property of client devices. + - The 1st cell specifies the channel configuration register: + - bit 13: SIF, source interface identifier, used to get the memory + interface identifier, + - bit 14: DIF, destination interface identifier, used to get the peripheral + interface identifier, + - bit 30-24: PERID, peripheral identifier. + +Example: + +dma1: dma-controller@f0004000 { + compatible = "atmel,sama5d4-dma"; + reg = <0xf0004000 0x200>; + interrupts = <50 4 0>; + #dma-cells = <1>; +}; + + +* DMA clients +DMA clients connected to the Atmel XDMA controller must use the format +described in the dma.txt file, using a one-cell specifier for each channel. +The two cells in order are: +1. A phandle pointing to the DMA controller. +2. Channel configuration register. Configurable fields are: + - bit 13: SIF, source interface identifier, used to get the memory + interface identifier, + - bit 14: DIF, destination interface identifier, used to get the peripheral + interface identifier, + - bit 30-24: PERID, peripheral identifier. + +Example: + +i2c2: i2c@f8024000 { + compatible = "atmel,at91sam9x5-i2c"; + reg = <0xf8024000 0x4000>; + interrupts = <34 4 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(6))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(7))>; + dma-names = "tx", "rx"; +}; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +Device-Tree bindings for Atmel's HLCDC (High LCD Controller) DRM driver + +The Atmel HLCDC Display Controller is subdevice of the HLCDC MFD device. +See ../mfd/atmel-hlcdc.txt for more details. + +Required properties: + - compatible: value should be "atmel,hlcdc-display-controller" + - pinctrl-names: the pin control state names. Should contain "default". + - pinctrl-0: should contain the default pinctrl states. + - #address-cells: should be set to 1. + - #size-cells: should be set to 0. + +Required children nodes: + Children nodes are encoding available output ports and their connections + to external devices using the OF graph reprensentation (see ../graph.txt). + At least one port node is required. + +Example: + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/input/atmel,maxtouch.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ Optional properties for main touchpad de experiment to determine which bit corresponds to which input. Use KEY_RESERVED for unused padding values. +- atmel,reset-gpio: Configure RESET GPIO. Required for regulator support. + +- atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This + will be downloaded from the firmware loader on probe to the device. + +- atmel,input_name: Override name of input device from the default. + Example: touch@4b { Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/media/i2c/ov2640.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/media/i2c/ov2640.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +* Omnivision OV2640 CMOS sensor + +The Omnivision OV2640 sensor support multiple resolutions output, such as +CIF, SVGA, UXGA. It also can support YUV422/420, RGB565/555 or raw RGB +output format. + +Required Properties: +- compatible: should be "ovti,ov2640" +- clocks: reference to the xvclk input clock. +- clock-names: should be "xvclk". + +Optional Properties: +- resetb-gpios: reference to the GPIO connected to the resetb pin, if any. +- pwdn-gpios: reference to the GPIO connected to the pwdn pin, if any. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + i2c1: i2c@f0018000 { + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1 &pinctrl_ov2640_pwdn &pinctrl_ov2640_resetb>; + + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + + clocks = <&pck1>; + clock-names = "xvclk"; + + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + }; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/media/i2c/ov5642.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/media/i2c/ov5642.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +* Omnivision OV5642 CMOS sensor + +The Omnivision OV5642 is a 1/4" color CMOS QSXGA (5 megapixel) image sensor. +It supports up to 2592x1944 resolution. It also support output YUV422/420, +RGB565/555/444, CCIR656, 8-bit compression or raw RGB data. + +Required Properties: +- compatible: should be "ovti,ov5642" +- clocks: reference to the xvclk input clock. +- clock-names: should be "xvclk". + +Optional Properties: +- resetb-gpios: reference to the GPIO connected to the resetb pin, if any. +- pwdn-gpios: reference to the GPIO connected to the pwdn pin, if any. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + i2c1: i2c@f0018000 { + ov5642: camera@0x3c { + compatible = "ovti,ov5642"; + reg = <0x3c>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck1 &pinctrl_sensor_pwdn &pinctrl_sensor_resetb>; + + resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; + + clocks = <&pck1>; + clock-names = "xvclk"; + + assigned-clocks = <&pck1>; + assigned-clock-rates = <25000000>; + + port { + ov5642_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; + }; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +Device-Tree bindings for Atmel's HLCDC (High LCD Controller) MFD driver + +Required properties: + - compatible: value should be one of the following: + "atmel,sama5d3-hlcdc" + "atmel,at91sam9n12-hlcdc" + "atmel,at91sam9x5-hlcdc" + - reg: base address and size of the HLCDC device registers. + - clock-names: the name of the 3 clocks requested by the HLCDC device. + Should contain "periph_clk", "sys_clk" and "slow_clk". + - clocks: should contain the 3 clocks requested by the HLCDC device. + - interrupts: should contain the description of the HLCDC interrupt line + +The HLCDC IP exposes two subdevices: + - a PWM chip: see ../pwm/atmel-hlcdc-pwm.txt + - a Display Controller: see ../drm/atmel-hlcdc-dc.txt + +Example: + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + status = "disabled"; + + hlcdc-display-controller { + compatible = "atmel,hlcdc-display-controller"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + hlcdc_panel_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_input>; + }; + }; + }; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/mtd/atmel-nand.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/devicetree/bindings/mtd/atmel-nand.txt +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/mtd/atmel-nand.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ Atmel NAND flash Required properties: -- compatible : "atmel,at91rm9200-nand". +- compatible : should be "atmel,at91rm9200-nand" or "atmel,sama5d4-nand". - reg : should specify localbus address and size used for the chip, and hardware ECC controller if available. If the hardware ECC is PMECC, it should contain address and size for - PMECC, PMECC Error Location controller and ROM which has lookup tables. + PMECC and PMECC Error Location controller. + The PMECC lookup table address and size in ROM is optional. If not + specified, driver will build it in runtime. - atmel,nand-addr-offset : offset for the address latch. - atmel,nand-cmd-offset : offset for the command latch. - #address-cells, #size-cells : Must be present if the device has sub-nodes @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:32 @ Optional properties: are: 512, 1024. - atmel,pmecc-lookup-table-offset : includes two offsets of lookup table in ROM for different sector size. First one is for sector size 512, the next is for - sector size 1024. + sector size 1024. If not specified, driver will build the table in runtime. - nand-bus-width : 8 or 16 bus width if not present 8 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false - Nand Flash Controller(NFC) is a slave driver under Atmel nand flash Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +QiaoDian XianShi Corporation 4"3 TFT LCD panel + +Required properties: +- compatible: should be "qd,qd43003c0-40" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +Device-Tree bindings for Atmel's HLCDC (High-end LCD Controller) PWM driver + +The Atmel HLCDC PWM is subdevice of the HLCDC MFD device. +See ../mfd/atmel-hlcdc.txt for more details. + +Required properties: + - compatible: value should be one of the following: + "atmel,hlcdc-pwm" + - pinctr-names: the pin control state names. Should contain "default". + - pinctrl-0: should contain the pinctrl states described by pinctrl + default. + - #pwm-cells: should be set to 3. This PWM chip use the default 3 cells + bindings defined in pwm.txt in this directory. + +Example: + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/rtc/atmel,at91sam9-rtc.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/rtc/atmel,at91sam9-rtc.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +Atmel AT91SAM9260 Real Time Timer + +Required properties: +- compatible: should be: "atmel,at91sam9260-rtt" +- reg: should encode the memory region of the RTT controller +- interrupts: rtt alarm/event interrupt +- clocks: should contain the 32 KHz slow clk that will drive the RTT block. +- atmel,rtt-rtc-time-reg: should encode the GPBR register used to store + the time base when the RTT is used as an RTC. + The first cell should point to the GPBR node and the second one + encode the offset within the GPBR block (or in other words, the + GPBR register used to store the time base). + + +Example: + +rtt@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 4 7>; + clocks = <&clk32k>; + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; +}; Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/sound/wm8904.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/devicetree/bindings/sound/wm8904.txt +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/sound/wm8904.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:6 @ WM8904 audio CODEC This device supports I2C only. Required properties: - - compatible: "wlf,wm8904" + - compatible: "wlf,wm8904" or "wlf,wm8912" - reg: the I2C address of the device. - clock-names: "mclk" - clocks: reference to Index: linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/usb/atmel-usb.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/devicetree/bindings/usb/atmel-usb.txt +++ linux-3.18.13-rt10-r7s4/Documentation/devicetree/bindings/usb/atmel-usb.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:8 @ OHCI Required properties: - compatible: Should be "atmel,at91rm9200-ohci" for USB controllers used in host mode. + - reg: Address and length of the register set for the device + - interrupts: Should contain ehci interrupt + - clocks: Should reference the peripheral, host and system clocks + - clock-names: Should contains two strings + "ohci_clk" for the peripheral clock + "hclk" for the host clock + "uhpck" for the system clock - num-ports: Number of ports. - atmel,vbus-gpio: If present, specifies a gpio that needs to be activated for the bus to be powered. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:24 @ Required properties: usb0: ohci@00500000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x100000>; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; + clock-names = "ohci_clk", "hclk", "uhpck"; interrupts = <20 4>; num-ports = <2>; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:35 @ EHCI Required properties: - compatible: Should be "atmel,at91sam9g45-ehci" for USB controllers used in host mode. + - reg: Address and length of the register set for the device + - interrupts: Should contain ehci interrupt + - clocks: Should reference the peripheral and the UTMI clocks + - clock-names: Should contains two strings + "ehci_clk" for the peripheral clock + "usb_clk" for the UTMI clock usb1: ehci@00800000 { compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00800000 0x100000>; interrupts = <22 4>; + clocks = <&utmi>, <&uhphs_clk>; + clock-names = "usb_clk", "ehci_clk"; }; AT91 USB device controller @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:65 @ usb1: gadget@fffa4000 { compatible = "atmel,at91rm9200-udc"; reg = <0xfffa4000 0x4000>; interrupts = <10 4>; + clocks = <&udc_clk>, <&udpck>; + clock-names = "pclk", "hclk"; atmel,vbus-gpio = <&pioC 5 0>; }; Atmel High-Speed USB device controller Required properties: - - compatible: Should be "atmel,at91sam9rl-udc" + - compatible: Should be one of the following + "at91sam9rl-udc" + "at91sam9g45-udc" + "sama5d3-udc" - reg: Address and length of the register set for the device - interrupts: Should contain usba interrupt + - clocks: Should reference the peripheral and host clocks + - clock-names: Should contains two strings + "pclk" for the peripheral clock + "hclk" for the host clock - ep childnode: To specify the number of endpoints and their properties. Optional properties: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:104 @ usb2: gadget@fff78000 { reg = <0x00600000 0x80000 0xfff78000 0x400>; interrupts = <27 4 0>; + clocks = <&utmi>, <&udphs_clk>; + clock-names = "hclk", "pclk"; atmel,vbus-gpio = <&pioB 19 0>; ep0 { Index: linux-3.18.13-rt10-r7s4/Documentation/dmaengine/provider.txt =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/Documentation/dmaengine/provider.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +DMAengine controller documentation +================================== + +Hardware Introduction ++++++++++++++++++++++ + +Most of the Slave DMA controllers have the same general principles of +operations. + +They have a given number of channels to use for the DMA transfers, and +a given number of requests lines. + +Requests and channels are pretty much orthogonal. Channels can be used +to serve several to any requests. To simplify, channels are the +entities that will be doing the copy, and requests what endpoints are +involved. + +The request lines actually correspond to physical lines going from the +DMA-eligible devices to the controller itself. Whenever the device +will want to start a transfer, it will assert a DMA request (DRQ) by +asserting that request line. + +A very simple DMA controller would only take into account a single +parameter: the transfer size. At each clock cycle, it would transfer a +byte of data from one buffer to another, until the transfer size has +been reached. + +That wouldn't work well in the real world, since slave devices might +require a specific number of bits to be transferred in a single +cycle. For example, we may want to transfer as much data as the +physical bus allows to maximize performances when doing a simple +memory copy operation, but our audio device could have a narrower FIFO +that requires data to be written exactly 16 or 24 bits at a time. This +is why most if not all of the DMA controllers can adjust this, using a +parameter called the transfer width. + +Moreover, some DMA controllers, whenever the RAM is used as a source +or destination, can group the reads or writes in memory into a buffer, +so instead of having a lot of small memory accesses, which is not +really efficient, you'll get several bigger transfers. This is done +using a parameter called the burst size, that defines how many single +reads/writes it's allowed to do without the controller splitting the +transfer into smaller sub-transfers. + +Our theoretical DMA controller would then only be able to do transfers +that involve a single contiguous block of data. However, some of the +transfers we usually have are not, and want to copy data from +non-contiguous buffers to a contiguous buffer, which is called +scatter-gather. + +DMAEngine, at least for mem2dev transfers, require support for +scatter-gather. So we're left with two cases here: either we have a +quite simple DMA controller that doesn't support it, and we'll have to +implement it in software, or we have a more advanced DMA controller, +that implements in hardware scatter-gather. + +The latter are usually programmed using a collection of chunks to +transfer, and whenever the transfer is started, the controller will go +over that collection, doing whatever we programmed there. + +This collection is usually either a table or a linked list. You will +then push either the address of the table and its number of elements, +or the first item of the list to one channel of the DMA controller, +and whenever a DRQ will be asserted, it will go through the collection +to know where to fetch the data from. + +Either way, the format of this collection is completely dependent on +your hardware. Each DMA controller will require a different structure, +but all of them will require, for every chunk, at least the source and +destination addresses, whether it should increment these addresses or +not and the three parameters we saw earlier: the burst size, the +transfer width and the transfer size. + +The one last thing is that usually, slave devices won't issue DRQ by +default, and you have to enable this in your slave device driver first +whenever you're willing to use DMA. + +These were just the general memory-to-memory (also called mem2mem) or +memory-to-device (mem2dev) kind of transfers. Most devices often +support other kind of transfers or memory operations that dmaengine +support and will be detailed later in this document. + +DMA Support in Linux +++++++++++++++++++++ + +Historically, DMA controller drivers have been implemented using the +async TX API, to offload operations such as memory copy, XOR, +cryptography, etc., basically any memory to memory operation. + +Over time, the need for memory to device transfers arose, and +dmaengine was extended. Nowadays, the async TX API is written as a +layer on top of dmaengine, and acts as a client. Still, dmaengine +accommodates that API in some cases, and made some design choices to +ensure that it stayed compatible. + +For more information on the Async TX API, please look the relevant +documentation file in Documentation/crypto/async-tx-api.txt. + +DMAEngine Registration +++++++++++++++++++++++ + +struct dma_device Initialization +-------------------------------- + +Just like any other kernel framework, the whole DMAEngine registration +relies on the driver filling a structure and registering against the +framework. In our case, that structure is dma_device. + +The first thing you need to do in your driver is to allocate this +structure. Any of the usual memory allocators will do, but you'll also +need to initialize a few fields in there: + + * channels: should be initialized as a list using the + INIT_LIST_HEAD macro for example + + * src_addr_widths: + - should contain a bitmask of the supported source transfer width + + * dst_addr_widths: + - should contain a bitmask of the supported destination transfer + width + + * directions: + - should contain a bitmask of the supported slave directions + (i.e. excluding mem2mem transfers) + + * residue_granularity: + - Granularity of the transfer residue reported to dma_set_residue. + - This can be either: + + Descriptor + -> Your device doesn't support any kind of residue + reporting. The framework will only know that a particular + transaction descriptor is done. + + Segment + -> Your device is able to report which chunks have been + transferred + + Burst + -> Your device is able to report which burst have been + transferred + + * dev: should hold the pointer to the struct device associated + to your current driver instance. + +Supported transaction types +--------------------------- + +The next thing you need is to set which transaction types your device +(and driver) supports. + +Our dma_device structure has a field called cap_mask that holds the +various types of transaction supported, and you need to modify this +mask using the dma_cap_set function, with various flags depending on +transaction types you support as an argument. + +All those capabilities are defined in the dma_transaction_type enum, +in include/linux/dmaengine.h + +Currently, the types available are: + * DMA_MEMCPY + - The device is able to do memory to memory copies + + * DMA_XOR + - The device is able to perform XOR operations on memory areas + - Used to accelerate XOR intensive tasks, such as RAID5 + + * DMA_XOR_VAL + - The device is able to perform parity check using the XOR + algorithm against a memory buffer. + + * DMA_PQ + - The device is able to perform RAID6 P+Q computations, P being a + simple XOR, and Q being a Reed-Solomon algorithm. + + * DMA_PQ_VAL + - The device is able to perform parity check using RAID6 P+Q + algorithm against a memory buffer. + + * DMA_INTERRUPT + - The device is able to trigger a dummy transfer that will + generate periodic interrupts + - Used by the client drivers to register a callback that will be + called on a regular basis through the DMA controller interrupt + + * DMA_SG + - The device supports memory to memory scatter-gather + transfers. + - Even though a plain memcpy can look like a particular case of a + scatter-gather transfer, with a single chunk to transfer, it's a + distinct transaction type in the mem2mem transfers case + + * DMA_PRIVATE + - The devices only supports slave transfers, and as such isn't + available for async transfers. + + * DMA_ASYNC_TX + - Must not be set by the device, and will be set by the framework + if needed + - /* TODO: What is it about? */ + + * DMA_SLAVE + - The device can handle device to memory transfers, including + scatter-gather transfers. + - While in the mem2mem case we were having two distinct types to + deal with a single chunk to copy or a collection of them, here, + we just have a single transaction type that is supposed to + handle both. + - If you want to transfer a single contiguous memory buffer, + simply build a scatter list with only one item. + + * DMA_CYCLIC + - The device can handle cyclic transfers. + - A cyclic transfer is a transfer where the chunk collection will + loop over itself, with the last item pointing to the first. + - It's usually used for audio transfers, where you want to operate + on a single ring buffer that you will fill with your audio data. + + * DMA_INTERLEAVE + - The device supports interleaved transfer. + - These transfers can transfer data from a non-contiguous buffer + to a non-contiguous buffer, opposed to DMA_SLAVE that can + transfer data from a non-contiguous data set to a continuous + destination buffer. + - It's usually used for 2d content transfers, in which case you + want to transfer a portion of uncompressed data directly to the + display to print it + +These various types will also affect how the source and destination +addresses change over time. + +Addresses pointing to RAM are typically incremented (or decremented) +after each transfer. In case of a ring buffer, they may loop +(DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO) +are typically fixed. + +Device operations +----------------- + +Our dma_device structure also requires a few function pointers in +order to implement the actual logic, now that we described what +operations we were able to perform. + +The functions that we have to fill in there, and hence have to +implement, obviously depend on the transaction types you reported as +supported. + + * device_alloc_chan_resources + * device_free_chan_resources + - These functions will be called whenever a driver will call + dma_request_channel or dma_release_channel for the first/last + time on the channel associated to that driver. + - They are in charge of allocating/freeing all the needed + resources in order for that channel to be useful for your + driver. + - These functions can sleep. + + * device_prep_dma_* + - These functions are matching the capabilities you registered + previously. + - These functions all take the buffer or the scatterlist relevant + for the transfer being prepared, and should create a hardware + descriptor or a list of hardware descriptors from it + - These functions can be called from an interrupt context + - Any allocation you might do should be using the GFP_NOWAIT + flag, in order not to potentially sleep, but without depleting + the emergency pool either. + - Drivers should try to pre-allocate any memory they might need + during the transfer setup at probe time to avoid putting to + much pressure on the nowait allocator. + + - It should return a unique instance of the + dma_async_tx_descriptor structure, that further represents this + particular transfer. + + - This structure can be initialized using the function + dma_async_tx_descriptor_init. + - You'll also need to set two fields in this structure: + + flags: + TODO: Can it be modified by the driver itself, or + should it be always the flags passed in the arguments + + + tx_submit: A pointer to a function you have to implement, + that is supposed to push the current + transaction descriptor to a pending queue, waiting + for issue_pending to be called. + + * device_issue_pending + - Takes the first transaction descriptor in the pending queue, + and starts the transfer. Whenever that transfer is done, it + should move to the next transaction in the list. + - This function can be called in an interrupt context + + * device_tx_status + - Should report the bytes left to go over on the given channel + - Should only care about the transaction descriptor passed as + argument, not the currently active one on a given channel + - The tx_state argument might be NULL + - Should use dma_set_residue to report it + - In the case of a cyclic transfer, it should only take into + account the current period. + - This function can be called in an interrupt context. + + * device_config + - Reconfigures the channel with the configuration given as + argument + - This command should NOT perform synchronously, or on any + currently queued transfers, but only on subsequent ones + - In this case, the function will receive a dma_slave_config + structure pointer as an argument, that will detail which + configuration to use. + - Even though that structure contains a direction field, this + field is deprecated in favor of the direction argument given to + the prep_* functions + - This call is only required for slave operations. This should NOT be + set or expected to be set for memcpy operations + + * device_pause + - Pauses a transfer on the channel + - This command should operate synchronously on the channel, + pausing right away the work of the given channel + + * device_resume + - Resumes a transfer on the channel + - This command should operate synchronously on the channel, + pausing right away the work of the given channel + + * device_terminate_all + - Aborts all the pending and ongoing transfers on the channel + - This command should operate synchronously on the channel, + terminating right away all the channels + +Misc notes (stuff that should be documented, but don't really know +where to put them) +------------------------------------------------------------------ + * dma_run_dependencies + - Should be called at the end of an async TX transfer, and can be + ignored in the slave transfers case. + - Makes sure that dependent operations are run before marking it + as complete. + + * dma_cookie_t + - it's a DMA transaction ID that will increment over time. + - Not really relevant any more since the introduction of virt-dma + that abstracts it away. + + * DMA_CTRL_ACK + - Undocumented feature + - No one really has an idea of what it's about, besides being + related to reusing the DMA transaction descriptors or having + additional transactions added to it in the async-tx API + - Useless in the case of the slave API + +General Design Notes +-------------------- + +Most of the DMAEngine drivers you'll see are based on a similar design +that handles the end of transfer interrupts in the handler, but defer +most work to a tasklet, including the start of a new transfer whenever +the previous transfer ended. + +This is a rather inefficient design though, because the inter-transfer +latency will be not only the interrupt latency, but also the +scheduling latency of the tasklet, which will leave the channel idle +in between, which will slow down the global transfer rate. + +You should avoid this kind of practice, and instead of electing a new +transfer in your tasklet, move that part to the interrupt handler in +order to have a shorter idle window (that we can't really avoid +anyway). + +Glossary +-------- + +Burst: A number of consecutive read or write operations + that can be queued to buffers before being flushed to + memory. +Chunk: A contiguous collection of bursts +Transfer: A collection of chunks (be it contiguous or not) Index: linux-3.18.13-rt10-r7s4/Documentation/DocBook/media/v4l/subdev-formats.xml =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/DocBook/media/v4l/subdev-formats.xml +++ linux-3.18.13-rt10-r7s4/Documentation/DocBook/media/v4l/subdev-formats.xml @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:89 @ green and 5-bit blue values padded on the high bit, transferred as 2 8-bit samples per pixel with the most significant bits (padding, red and half of the green value) transferred first will be named - <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>. + <constant>MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE</constant>. </para> <para>The following tables list existing packed RGB formats.</para> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:179 @ </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-BE"> - <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry> + <row id="MEDIA-BUS-FMT-RGB444-1X12"> + <entry>MEDIA_BUS_FMT_RGB444_1X12</entry> + <entry>0x100d</entry> + <entry></entry> + &dash-ent-20; + <entry>r<subscript>3</subscript></entry> + <entry>r<subscript>2</subscript></entry> + <entry>r<subscript>1</subscript></entry> + <entry>r<subscript>0</subscript></entry> + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> + <entry>b<subscript>3</subscript></entry> + <entry>b<subscript>2</subscript></entry> + <entry>b<subscript>1</subscript></entry> + <entry>b<subscript>0</subscript></entry> + </row> + <row id="MEDIA-BUS-FMT-RGB444-2X8-PADHI-BE"> + <entry>MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE</entry> <entry>0x1001</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:225 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-LE"> - <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry> + <row id="MEDIA-BUS-FMT-RGB444-2X8-PADHI-LE"> + <entry>MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE</entry> <entry>0x1002</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:253 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-BE"> - <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry> + <row id="MEDIA-BUS-FMT-RGB555-2X8-PADHI-BE"> + <entry>MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE</entry> <entry>0x1003</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:281 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-LE"> - <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry> + <row id="MEDIA-BUS-FMT-RGB555-2X8-PADHI-LE"> + <entry>MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE</entry> <entry>0x1004</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:309 @ <entry>g<subscript>4</subscript></entry> <entry>g<subscript>3</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-BGR565-2X8-BE"> - <entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry> + <row id="MEDIA-BUS-FMT-RGB565-1X16"> + <entry>MEDIA_BUS_FMT_RGB565_1X16</entry> + <entry>0x100d</entry> + <entry></entry> + &dash-ent-16; + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> + <entry>r<subscript>2</subscript></entry> + <entry>r<subscript>1</subscript></entry> + <entry>r<subscript>0</subscript></entry> + <entry>g<subscript>5</subscript></entry> + <entry>g<subscript>4</subscript></entry> + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> + <entry>b<subscript>4</subscript></entry> + <entry>b<subscript>3</subscript></entry> + <entry>b<subscript>2</subscript></entry> + <entry>b<subscript>1</subscript></entry> + <entry>b<subscript>0</subscript></entry> + </row> + <row id="MEDIA-BUS-FMT-BGR565-2X8-BE"> + <entry>MEDIA_BUS_FMT_BGR565_2X8_BE</entry> <entry>0x1005</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:359 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-BGR565-2X8-LE"> - <entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry> + <row id="MEDIA-BUS-FMT-BGR565-2X8-LE"> + <entry>MEDIA_BUS_FMT_BGR565_2X8_LE</entry> <entry>0x1006</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:387 @ <entry>g<subscript>4</subscript></entry> <entry>g<subscript>3</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB565-2X8-BE"> - <entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry> + <row id="MEDIA-BUS-FMT-RGB565-2X8-BE"> + <entry>MEDIA_BUS_FMT_RGB565_2X8_BE</entry> <entry>0x1007</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:415 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB565-2X8-LE"> - <entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry> + <row id="MEDIA-BUS-FMT-RGB565-2X8-LE"> + <entry>MEDIA_BUS_FMT_RGB565_2X8_LE</entry> <entry>0x1008</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:443 @ <entry>g<subscript>4</subscript></entry> <entry>g<subscript>3</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB666-1X18"> - <entry>V4L2_MBUS_FMT_RGB666_1X18</entry> + <row id="MEDIA-BUS-FMT-RGB666-1X18"> + <entry>MEDIA_BUS_FMT_RGB666_1X18</entry> <entry>0x1009</entry> <entry></entry> &dash-ent-14; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:467 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB888-1X24"> - <entry>V4L2_MBUS_FMT_RGB888_1X24</entry> + <row id="MEDIA-BUS-FMT-RGB888-1X24"> + <entry>MEDIA_BUS_FMT_RGB888_1X24</entry> <entry>0x100a</entry> <entry></entry> &dash-ent-8; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:497 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB888-2X12-BE"> - <entry>V4L2_MBUS_FMT_RGB888_2X12_BE</entry> + <row id="MEDIA-BUS-FMT-RGB888-2X12-BE"> + <entry>MEDIA_BUS_FMT_RGB888_2X12_BE</entry> <entry>0x100b</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:533 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-RGB888-2X12-LE"> - <entry>V4L2_MBUS_FMT_RGB888_2X12_LE</entry> + <row id="MEDIA-BUS-FMT-RGB888-2X12-LE"> + <entry>MEDIA_BUS_FMT_RGB888_2X12_LE</entry> <entry>0x100c</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:569 @ <entry>g<subscript>5</subscript></entry> <entry>g<subscript>4</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-ARGB888-1X32"> - <entry>V4L2_MBUS_FMT_ARGB888_1X32</entry> + <row id="MEDIA-BUS-FMT-ARGB888-1X32"> + <entry>MEDIA_BUS_FMT_ARGB888_1X32</entry> <entry>0x100d</entry> <entry></entry> <entry>a<subscript>7</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:643 @ <para>For instance, a format with uncompressed 10-bit Bayer components arranged in a red, green, green, blue pattern transferred as 2 8-bit samples per pixel with the least significant bits transferred first will - be named <constant>V4L2_MBUS_FMT_SRGGB10_2X8_PADHI_LE</constant>. + be named <constant>MEDIA_BUS_FMT_SRGGB10_2X8_PADHI_LE</constant>. </para> <figure id="bayer-patterns"> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:706 @ </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-SBGGR8-1X8"> - <entry>V4L2_MBUS_FMT_SBGGR8_1X8</entry> + <row id="MEDIA-BUS-FMT-SBGGR8-1X8"> + <entry>MEDIA_BUS_FMT_SBGGR8_1X8</entry> <entry>0x3001</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:723 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGBRG8-1X8"> - <entry>V4L2_MBUS_FMT_SGBRG8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGBRG8-1X8"> + <entry>MEDIA_BUS_FMT_SGBRG8_1X8</entry> <entry>0x3013</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:740 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGRBG8-1X8"> - <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGRBG8-1X8"> + <entry>MEDIA_BUS_FMT_SGRBG8_1X8</entry> <entry>0x3002</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:757 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SRGGB8-1X8"> - <entry>V4L2_MBUS_FMT_SRGGB8_1X8</entry> + <row id="MEDIA-BUS-FMT-SRGGB8-1X8"> + <entry>MEDIA_BUS_FMT_SRGGB8_1X8</entry> <entry>0x3014</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:774 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-ALAW8-1X8"> - <entry>V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-ALAW8-1X8"> + <entry>MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8</entry> <entry>0x3015</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:791 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGBRG10-ALAW8-1X8"> - <entry>V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGBRG10-ALAW8-1X8"> + <entry>MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8</entry> <entry>0x3016</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:808 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGRBG10-ALAW8-1X8"> - <entry>V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGRBG10-ALAW8-1X8"> + <entry>MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8</entry> <entry>0x3017</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:825 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SRGGB10-ALAW8-1X8"> - <entry>V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8</entry> + <row id="MEDIA-BUS-FMT-SRGGB10-ALAW8-1X8"> + <entry>MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8</entry> <entry>0x3018</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:842 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8"> - <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-DPCM8-1X8"> + <entry>MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8</entry> <entry>0x300b</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:859 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGBRG10-DPCM8-1X8"> - <entry>V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGBRG10-DPCM8-1X8"> + <entry>MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8</entry> <entry>0x300c</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:876 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGRBG10-DPCM8-1X8"> - <entry>V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8</entry> + <row id="MEDIA-BUS-FMT-SGRBG10-DPCM8-1X8"> + <entry>MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8</entry> <entry>0x3009</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:893 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SRGGB10-DPCM8-1X8"> - <entry>V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8</entry> + <row id="MEDIA-BUS-FMT-SRGGB10-DPCM8-1X8"> + <entry>MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8</entry> <entry>0x300d</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:910 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-BE"> - <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-BE"> + <entry>MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE</entry> <entry>0x3003</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:944 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-LE"> - <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-LE"> + <entry>MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE</entry> <entry>0x3004</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:978 @ <entry>b<subscript>9</subscript></entry> <entry>b<subscript>8</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-BE"> - <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-BE"> + <entry>MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE</entry> <entry>0x3005</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1012 @ <entry>0</entry> <entry>0</entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-LE"> - <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-LE"> + <entry>MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE</entry> <entry>0x3006</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1046 @ <entry>b<subscript>3</subscript></entry> <entry>b<subscript>2</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR10-1X10"> - <entry>V4L2_MBUS_FMT_SBGGR10_1X10</entry> + <row id="MEDIA-BUS-FMT-SBGGR10-1X10"> + <entry>MEDIA_BUS_FMT_SBGGR10_1X10</entry> <entry>0x3007</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1063 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGBRG10-1X10"> - <entry>V4L2_MBUS_FMT_SGBRG10_1X10</entry> + <row id="MEDIA-BUS-FMT-SGBRG10-1X10"> + <entry>MEDIA_BUS_FMT_SGBRG10_1X10</entry> <entry>0x300e</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1080 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGRBG10-1X10"> - <entry>V4L2_MBUS_FMT_SGRBG10_1X10</entry> + <row id="MEDIA-BUS-FMT-SGRBG10-1X10"> + <entry>MEDIA_BUS_FMT_SGRBG10_1X10</entry> <entry>0x300a</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1097 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SRGGB10-1X10"> - <entry>V4L2_MBUS_FMT_SRGGB10_1X10</entry> + <row id="MEDIA-BUS-FMT-SRGGB10-1X10"> + <entry>MEDIA_BUS_FMT_SRGGB10_1X10</entry> <entry>0x300f</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1114 @ <entry>r<subscript>1</subscript></entry> <entry>r<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SBGGR12-1X12"> - <entry>V4L2_MBUS_FMT_SBGGR12_1X12</entry> + <row id="MEDIA-BUS-FMT-SBGGR12-1X12"> + <entry>MEDIA_BUS_FMT_SBGGR12_1X12</entry> <entry>0x3008</entry> <entry></entry> <entry>b<subscript>11</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1131 @ <entry>b<subscript>1</subscript></entry> <entry>b<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGBRG12-1X12"> - <entry>V4L2_MBUS_FMT_SGBRG12_1X12</entry> + <row id="MEDIA-BUS-FMT-SGBRG12-1X12"> + <entry>MEDIA_BUS_FMT_SGBRG12_1X12</entry> <entry>0x3010</entry> <entry></entry> <entry>g<subscript>11</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1148 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SGRBG12-1X12"> - <entry>V4L2_MBUS_FMT_SGRBG12_1X12</entry> + <row id="MEDIA-BUS-FMT-SGRBG12-1X12"> + <entry>MEDIA_BUS_FMT_SGRBG12_1X12</entry> <entry>0x3011</entry> <entry></entry> <entry>g<subscript>11</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1165 @ <entry>g<subscript>1</subscript></entry> <entry>g<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-SRGGB12-1X12"> - <entry>V4L2_MBUS_FMT_SRGGB12_1X12</entry> + <row id="MEDIA-BUS-FMT-SRGGB12-1X12"> + <entry>MEDIA_BUS_FMT_SRGGB12_1X12</entry> <entry>0x3012</entry> <entry></entry> <entry>r<subscript>11</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1218 @ <para>For instance, a format where pixels are encoded as 8-bit YUV values downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in the - U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>. + U, Y, V, Y order will be named <constant>MEDIA_BUS_FMT_UYVY8_2X8</constant>. </para> <para><xref linkend="v4l2-mbus-pixelcode-yuv8"/> lists existing packed YUV @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1323 @ </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-Y8-1X8"> - <entry>V4L2_MBUS_FMT_Y8_1X8</entry> + <row id="MEDIA-BUS-FMT-Y8-1X8"> + <entry>MEDIA_BUS_FMT_Y8_1X8</entry> <entry>0x2001</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1337 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UV8-1X8"> - <entry>V4L2_MBUS_FMT_UV8_1X8</entry> + <row id="MEDIA-BUS-FMT-UV8-1X8"> + <entry>MEDIA_BUS_FMT_UV8_1X8</entry> <entry>0x2015</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1365 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY8-1_5X8"> - <entry>V4L2_MBUS_FMT_UYVY8_1_5X8</entry> + <row id="MEDIA-BUS-FMT-UYVY8-1_5X8"> + <entry>MEDIA_BUS_FMT_UYVY8_1_5X8</entry> <entry>0x2002</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1449 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY8-1_5X8"> - <entry>V4L2_MBUS_FMT_VYUY8_1_5X8</entry> + <row id="MEDIA-BUS-FMT-VYUY8-1_5X8"> + <entry>MEDIA_BUS_FMT_VYUY8_1_5X8</entry> <entry>0x2003</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1533 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV8-1_5X8"> - <entry>V4L2_MBUS_FMT_YUYV8_1_5X8</entry> + <row id="MEDIA-BUS-FMT-YUYV8-1_5X8"> + <entry>MEDIA_BUS_FMT_YUYV8_1_5X8</entry> <entry>0x2004</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1617 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU8-1_5X8"> - <entry>V4L2_MBUS_FMT_YVYU8_1_5X8</entry> + <row id="MEDIA-BUS-FMT-YVYU8-1_5X8"> + <entry>MEDIA_BUS_FMT_YVYU8_1_5X8</entry> <entry>0x2005</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1701 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY8-2X8"> - <entry>V4L2_MBUS_FMT_UYVY8_2X8</entry> + <row id="MEDIA-BUS-FMT-UYVY8-2X8"> + <entry>MEDIA_BUS_FMT_UYVY8_2X8</entry> <entry>0x2006</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1757 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY8-2X8"> - <entry>V4L2_MBUS_FMT_VYUY8_2X8</entry> + <row id="MEDIA-BUS-FMT-VYUY8-2X8"> + <entry>MEDIA_BUS_FMT_VYUY8_2X8</entry> <entry>0x2007</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1813 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV8-2X8"> - <entry>V4L2_MBUS_FMT_YUYV8_2X8</entry> + <row id="MEDIA-BUS-FMT-YUYV8-2X8"> + <entry>MEDIA_BUS_FMT_YUYV8_2X8</entry> <entry>0x2008</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1869 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU8-2X8"> - <entry>V4L2_MBUS_FMT_YVYU8_2X8</entry> + <row id="MEDIA-BUS-FMT-YVYU8-2X8"> + <entry>MEDIA_BUS_FMT_YVYU8_2X8</entry> <entry>0x2009</entry> <entry></entry> &dash-ent-24; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1925 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-Y10-1X10"> - <entry>V4L2_MBUS_FMT_Y10_1X10</entry> + <row id="MEDIA-BUS-FMT-Y10-1X10"> + <entry>MEDIA_BUS_FMT_Y10_1X10</entry> <entry>0x200a</entry> <entry></entry> &dash-ent-22; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1941 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY10-2X10"> - <entry>V4L2_MBUS_FMT_UYVY10_2X10</entry> + <row id="MEDIA-BUS-FMT-UYVY10-2X10"> + <entry>MEDIA_BUS_FMT_UYVY10_2X10</entry> <entry>0x2018</entry> <entry></entry> &dash-ent-22; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2005 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY10-2X10"> - <entry>V4L2_MBUS_FMT_VYUY10_2X10</entry> + <row id="MEDIA-BUS-FMT-VYUY10-2X10"> + <entry>MEDIA_BUS_FMT_VYUY10_2X10</entry> <entry>0x2019</entry> <entry></entry> &dash-ent-22; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2069 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV10-2X10"> - <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry> + <row id="MEDIA-BUS-FMT-YUYV10-2X10"> + <entry>MEDIA_BUS_FMT_YUYV10_2X10</entry> <entry>0x200b</entry> <entry></entry> &dash-ent-22; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2133 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU10-2X10"> - <entry>V4L2_MBUS_FMT_YVYU10_2X10</entry> + <row id="MEDIA-BUS-FMT-YVYU10-2X10"> + <entry>MEDIA_BUS_FMT_YVYU10_2X10</entry> <entry>0x200c</entry> <entry></entry> &dash-ent-22; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2197 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-Y12-1X12"> - <entry>V4L2_MBUS_FMT_Y12_1X12</entry> + <row id="MEDIA-BUS-FMT-Y12-1X12"> + <entry>MEDIA_BUS_FMT_Y12_1X12</entry> <entry>0x2013</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2215 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY8-1X16"> - <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry> + <row id="MEDIA-BUS-FMT-UYVY8-1X16"> + <entry>MEDIA_BUS_FMT_UYVY8_1X16</entry> <entry>0x200f</entry> <entry></entry> &dash-ent-16; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2259 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY8-1X16"> - <entry>V4L2_MBUS_FMT_VYUY8_1X16</entry> + <row id="MEDIA-BUS-FMT-VYUY8-1X16"> + <entry>MEDIA_BUS_FMT_VYUY8_1X16</entry> <entry>0x2010</entry> <entry></entry> &dash-ent-16; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2303 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV8-1X16"> - <entry>V4L2_MBUS_FMT_YUYV8_1X16</entry> + <row id="MEDIA-BUS-FMT-YUYV8-1X16"> + <entry>MEDIA_BUS_FMT_YUYV8_1X16</entry> <entry>0x2011</entry> <entry></entry> &dash-ent-16; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2347 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU8-1X16"> - <entry>V4L2_MBUS_FMT_YVYU8_1X16</entry> + <row id="MEDIA-BUS-FMT-YVYU8-1X16"> + <entry>MEDIA_BUS_FMT_YVYU8_1X16</entry> <entry>0x2012</entry> <entry></entry> &dash-ent-16; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2391 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YDYUYDYV8-1X16"> - <entry>V4L2_MBUS_FMT_YDYUYDYV8_1X16</entry> + <row id="MEDIA-BUS-FMT-YDYUYDYV8-1X16"> + <entry>MEDIA_BUS_FMT_YDYUYDYV8_1X16</entry> <entry>0x2014</entry> <entry></entry> &dash-ent-16; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2479 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY10-1X20"> - <entry>V4L2_MBUS_FMT_UYVY10_1X20</entry> + <row id="MEDIA-BUS-FMT-UYVY10-1X20"> + <entry>MEDIA_BUS_FMT_UYVY10_1X20</entry> <entry>0x201a</entry> <entry></entry> &dash-ent-12; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2531 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY10-1X20"> - <entry>V4L2_MBUS_FMT_VYUY10_1X20</entry> + <row id="MEDIA-BUS-FMT-VYUY10-1X20"> + <entry>MEDIA_BUS_FMT_VYUY10_1X20</entry> <entry>0x201b</entry> <entry></entry> &dash-ent-12; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2583 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV10-1X20"> - <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry> + <row id="MEDIA-BUS-FMT-YUYV10-1X20"> + <entry>MEDIA_BUS_FMT_YUYV10_1X20</entry> <entry>0x200d</entry> <entry></entry> &dash-ent-12; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2635 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU10-1X20"> - <entry>V4L2_MBUS_FMT_YVYU10_1X20</entry> + <row id="MEDIA-BUS-FMT-YVYU10-1X20"> + <entry>MEDIA_BUS_FMT_YVYU10_1X20</entry> <entry>0x200e</entry> <entry></entry> &dash-ent-12; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2687 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUV10-1X30"> - <entry>V4L2_MBUS_FMT_YUV10_1X30</entry> + <row id="MEDIA-BUS-FMT-YUV10-1X30"> + <entry>MEDIA_BUS_FMT_YUV10_1X30</entry> <entry>0x2016</entry> <entry></entry> <entry>-</entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2724 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-AYUV8-1X32"> - <entry>V4L2_MBUS_FMT_AYUV8_1X32</entry> + <row id="MEDIA-BUS-FMT-AYUV8-1X32"> + <entry>MEDIA_BUS_FMT_AYUV8_1X32</entry> <entry>0x2017</entry> <entry></entry> <entry>a<subscript>7</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2761 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY12-2X12"> - <entry>V4L2_MBUS_FMT_UYVY12_2X12</entry> + <row id="MEDIA-BUS-FMT-UYVY12-2X12"> + <entry>MEDIA_BUS_FMT_UYVY12_2X12</entry> <entry>0x201c</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2833 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY12-2X12"> - <entry>V4L2_MBUS_FMT_VYUY12_2X12</entry> + <row id="MEDIA-BUS-FMT-VYUY12-2X12"> + <entry>MEDIA_BUS_FMT_VYUY12_2X12</entry> <entry>0x201d</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2905 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV12-2X12"> - <entry>V4L2_MBUS_FMT_YUYV12_2X12</entry> + <row id="MEDIA-BUS-FMT-YUYV12-2X12"> + <entry>MEDIA_BUS_FMT_YUYV12_2X12</entry> <entry>0x201e</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2977 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU12-2X12"> - <entry>V4L2_MBUS_FMT_YVYU12_2X12</entry> + <row id="MEDIA-BUS-FMT-YVYU12-2X12"> + <entry>MEDIA_BUS_FMT_YVYU12_2X12</entry> <entry>0x201f</entry> <entry></entry> &dash-ent-20; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3049 @ <entry>u<subscript>1</subscript></entry> <entry>u<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-UYVY12-1X24"> - <entry>V4L2_MBUS_FMT_UYVY12_1X24</entry> + <row id="MEDIA-BUS-FMT-UYVY12-1X24"> + <entry>MEDIA_BUS_FMT_UYVY12_1X24</entry> <entry>0x2020</entry> <entry></entry> &dash-ent-8; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3109 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-VYUY12-1X24"> - <entry>V4L2_MBUS_FMT_VYUY12_1X24</entry> + <row id="MEDIA-BUS-FMT-VYUY12-1X24"> + <entry>MEDIA_BUS_FMT_VYUY12_1X24</entry> <entry>0x2021</entry> <entry></entry> &dash-ent-8; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3169 @ <entry>y<subscript>1</subscript></entry> <entry>y<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YUYV12-1X24"> - <entry>V4L2_MBUS_FMT_YUYV12_1X24</entry> + <row id="MEDIA-BUS-FMT-YUYV12-1X24"> + <entry>MEDIA_BUS_FMT_YUYV12_1X24</entry> <entry>0x2022</entry> <entry></entry> &dash-ent-8; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3229 @ <entry>v<subscript>1</subscript></entry> <entry>v<subscript>0</subscript></entry> </row> - <row id="V4L2-MBUS-FMT-YVYU12-1X24"> - <entry>V4L2_MBUS_FMT_YVYU12_1X24</entry> + <row id="MEDIA-BUS-FMT-YVYU12-1X24"> + <entry>MEDIA_BUS_FMT_YVYU12_1X24</entry> <entry>0x2023</entry> <entry></entry> &dash-ent-8; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3409 @ </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-AHSV8888-1X32"> - <entry>V4L2_MBUS_FMT_AHSV8888_1X32</entry> + <row id="MEDIA-BUS-FMT-AHSV8888-1X32"> + <entry>MEDIA_BUS_FMT_AHSV8888_1X32</entry> <entry>0x6001</entry> <entry></entry> <entry>a<subscript>7</subscript></entry> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3465 @ </para> <para>For instance, for a JPEG baseline process and an 8-bit bus width - the format will be named <constant>V4L2_MBUS_FMT_JPEG_1X8</constant>. + the format will be named <constant>MEDIA_BUS_FMT_JPEG_1X8</constant>. </para> <para>The following table lists existing JPEG compressed formats.</para> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3484 @ </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-JPEG-1X8"> - <entry>V4L2_MBUS_FMT_JPEG_1X8</entry> + <row id="MEDIA-BUS-FMT-JPEG-1X8"> + <entry>MEDIA_BUS_FMT_JPEG_1X8</entry> <entry>0x4001</entry> <entry>Besides of its usage for the parallel bus this format is recommended for transmission of JPEG data over MIPI CSI bus @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3527 @ interface and may change in the future.< </row> </thead> <tbody valign="top"> - <row id="V4L2-MBUS-FMT-S5C-UYVY-JPEG-1X8"> - <entry>V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8</entry> + <row id="MEDIA-BUS-FMT-S5C-UYVY-JPEG-1X8"> + <entry>MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8</entry> <entry>0x5001</entry> <entry> Interleaved raw UYVY and JPEG image format with embedded Index: linux-3.18.13-rt10-r7s4/Documentation/gpio/driver.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/gpio/driver.txt +++ linux-3.18.13-rt10-r7s4/Documentation/gpio/driver.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:161 @ Locking IRQ usage Input GPIOs can be used as IRQ signals. When this happens, a driver is requested to mark the GPIO as being used as an IRQ: - int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) + int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock is released: - void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) + void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) When implementing an irqchip inside a GPIO driver, these two functions should typically be called in the .startup() and .shutdown() callbacks from the Index: linux-3.18.13-rt10-r7s4/Documentation/power/suspend-and-interrupts.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/power/suspend-and-interrupts.txt +++ linux-3.18.13-rt10-r7s4/Documentation/power/suspend-and-interrupts.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:113 @ any special interrupt handling logic for IRQF_NO_SUSPEND and enable_irq_wake() ------------------------------------- -There are no valid reasons to use both enable_irq_wake() and the IRQF_NO_SUSPEND -flag on the same IRQ. +There are very few valid reasons to use both enable_irq_wake() and the +IRQF_NO_SUSPEND flag on the same IRQ, and it is never valid to use both for the +same device. First of all, if the IRQ is not shared, the rules for handling IRQF_NO_SUSPEND interrupts (interrupt handlers are invoked after suspend_device_irqs()) are @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:124 @ handlers are not invoked after suspend_d Second, both enable_irq_wake() and IRQF_NO_SUSPEND apply to entire IRQs and not to individual interrupt handlers, so sharing an IRQ between a system wakeup -interrupt source and an IRQF_NO_SUSPEND interrupt source does not make sense. +interrupt source and an IRQF_NO_SUSPEND interrupt source does not generally +make sense. + +In rare cases an IRQ can be shared between a wakeup device driver and an +IRQF_NO_SUSPEND user. In order for this to be safe, the wakeup device driver +must be able to discern spurious IRQs from genuine wakeup events (signalling +the latter to the core with pm_system_wakeup()), must use enable_irq_wake() to +ensure that the IRQ will function as a wakeup source, and must request the IRQ +with IRQF_COND_SUSPEND to tell the core that it meets these requirements. If +these requirements are not met, it is not valid to use IRQF_COND_SUSPEND. Index: linux-3.18.13-rt10-r7s4/Documentation/video4linux/soc-camera.txt =================================================================== --- linux-3.18.13-rt10-r7s4.orig/Documentation/video4linux/soc-camera.txt +++ linux-3.18.13-rt10-r7s4/Documentation/video4linux/soc-camera.txt @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:154 @ they are transferred over a media bus. S conveniently manage these formats. A table of standard transformations is maintained by soc-camera core, which describes, what FOURCC pixel format will be obtained, if a media-bus pixel format is stored in memory according to -certain rules. E.g. if V4L2_MBUS_FMT_YUYV8_2X8 data is sampled with 8 bits per +certain rules. E.g. if MEDIA_BUS_FMT_YUYV8_2X8 data is sampled with 8 bits per sample and stored in memory in the little-endian order with no gaps between bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These standard transformations will be used by soc-camera or by camera host drivers to Index: linux-3.18.13-rt10-r7s4/drivers/base/power/wakeup.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/base/power/wakeup.c +++ linux-3.18.13-rt10-r7s4/drivers/base/power/wakeup.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:733 @ void pm_system_wakeup(void) pm_abort_suspend = true; freeze_wake(); } +EXPORT_SYMBOL_GPL(pm_system_wakeup); void pm_wakeup_clear(void) { Index: linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-programmable.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/at91/clk-programmable.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-programmable.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ static unsigned long clk_programmable_re static long clk_programmable_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_clk) + struct clk_hw **best_parent_hw) { struct clk *parent = NULL; long best_rate = -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:87 @ static long clk_programmable_determine_r if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) { best_rate = tmp_rate; *best_parent_rate = parent_rate; - *best_parent_clk = parent; + *best_parent_hw = __clk_get_hw(parent); } if (!best_rate) Index: linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-slow.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/at91/clk-slow.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-slow.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ struct clk_sam9x5_slow { #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) +static struct clk *slow_clk; static int clk_slow_osc_prepare(struct clk_hw *hw) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:361 @ at91_clk_register_sam9x5_slow(void __iom clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:439 @ at91_clk_register_sam9260_slow(struct at clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:473 @ void __init of_at91sam9260_clk_slow_setu of_clk_add_provider(np, of_clk_src_simple_get, clk); } + +/* + * FIXME: All slow clk users are not properly claiming it (get + prepare + + * enable) before using it. + * If all users properly claiming this clock decide that they don't need it + * anymore (or are removed), it is disabled while faulty users are still + * requiring it, and the system hangs. + * Prevent this clock from being disabled until all users are properly + * requesting it. + * Once this is done we should remove this function and the slow_clk variable. + */ +static int __init of_at91_clk_slow_retain(void) +{ + if (!slow_clk) + return 0; + + __clk_get(slow_clk); + clk_prepare_enable(slow_clk); + + return 0; +} +arch_initcall(of_at91_clk_slow_retain); Index: linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-usb.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/at91/clk-usb.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/at91/clk-usb.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:59 @ static unsigned long at91sam9x5_clk_usb_ return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); } -static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long div; - - if (!rate) - return -EINVAL; - - if (rate >= *parent_rate) - return *parent_rate; - - div = DIV_ROUND_CLOSEST(*parent_rate, rate); - if (div > SAM9X5_USB_MAX_DIV + 1) - div = SAM9X5_USB_MAX_DIV + 1; +static long at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *best_parent_rate, + struct clk_hw **best_parent_hw) +{ + struct clk *parent = NULL; + long best_rate = -EINVAL; + unsigned long tmp_rate; + int best_diff = -1; + int tmp_diff; + int i; + + for (i = 0; i < __clk_get_num_parents(hw->clk); i++) { + int div; + + parent = clk_get_parent_by_index(hw->clk, i); + if (!parent) + continue; + + for (div = 1; div < SAM9X5_USB_MAX_DIV + 2; div++) { + unsigned long tmp_parent_rate; + + tmp_parent_rate = rate * div; + tmp_parent_rate = __clk_round_rate(parent, + tmp_parent_rate); + tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div); + if (tmp_rate < rate) + tmp_diff = rate - tmp_rate; + else + tmp_diff = tmp_rate - rate; + + if (best_diff < 0 || best_diff > tmp_diff) { + best_rate = tmp_rate; + best_diff = tmp_diff; + *best_parent_rate = tmp_parent_rate; + *best_parent_hw = __clk_get_hw(parent); + } + + if (!best_diff || tmp_rate < rate) + break; + } + + if (!best_diff) + break; + } - return DIV_ROUND_CLOSEST(*parent_rate, div); + return best_rate; } static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:155 @ static int at91sam9x5_clk_usb_set_rate(s static const struct clk_ops at91sam9x5_usb_ops = { .recalc_rate = at91sam9x5_clk_usb_recalc_rate, - .round_rate = at91sam9x5_clk_usb_round_rate, + .determine_rate = at91sam9x5_clk_usb_determine_rate, .get_parent = at91sam9x5_clk_usb_get_parent, .set_parent = at91sam9x5_clk_usb_set_parent, .set_rate = at91sam9x5_clk_usb_set_rate, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:193 @ static const struct clk_ops at91sam9n12_ .disable = at91sam9n12_clk_usb_disable, .is_enabled = at91sam9n12_clk_usb_is_enabled, .recalc_rate = at91sam9x5_clk_usb_recalc_rate, - .round_rate = at91sam9x5_clk_usb_round_rate, + .determine_rate = at91sam9x5_clk_usb_determine_rate, .set_rate = at91sam9x5_clk_usb_set_rate, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:213 @ at91sam9x5_clk_register_usb(struct at91_ init.ops = &at91sam9x5_usb_ops; init.parent_names = parent_names; init.num_parents = num_parents; - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT; usb->hw.init = &init; usb->pmc = pmc; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:242 @ at91sam9n12_clk_register_usb(struct at91 init.ops = &at91sam9n12_usb_ops; init.parent_names = &parent_name; init.num_parents = 1; - init.flags = CLK_SET_RATE_GATE; + init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; usb->hw.init = &init; usb->pmc = pmc; Index: linux-3.18.13-rt10-r7s4/drivers/clk/at91/pmc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/at91/pmc.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/at91/pmc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:83 @ static int pmc_irq_set_type(struct irq_d return 0; } +static void pmc_irq_suspend(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc->imr = pmc_read(pmc, AT91_PMC_IMR); + pmc_write(pmc, AT91_PMC_IDR, pmc->imr); +} + +static void pmc_irq_resume(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc_write(pmc, AT91_PMC_IER, pmc->imr); +} + static struct irq_chip pmc_irq = { .name = "PMC", .irq_disable = pmc_irq_mask, .irq_mask = pmc_irq_mask, .irq_unmask = pmc_irq_unmask, .irq_set_type = pmc_irq_set_type, + .irq_suspend = pmc_irq_suspend, + .irq_resume = pmc_irq_resume, }; static struct lock_class_key pmc_lock_class; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:235 @ static struct at91_pmc *__init at91_pmc_ goto out_free_pmc; pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); - if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc)) + if (request_irq(pmc->virq, pmc_irq_handler, + IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) goto out_remove_irqdomain; return pmc; Index: linux-3.18.13-rt10-r7s4/drivers/clk/at91/pmc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/at91/pmc.h +++ linux-3.18.13-rt10-r7s4/drivers/clk/at91/pmc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:36 @ struct at91_pmc { spinlock_t lock; const struct at91_pmc_caps *caps; struct irq_domain *irqdomain; + u32 imr; }; static inline void pmc_lock(struct at91_pmc *pmc) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:124 @ extern void __init of_at91sam9x5_clk_smd struct at91_pmc *pmc); #endif -#if defined(CONFIG_HAVE_AT91_SMD) +#if defined(CONFIG_HAVE_AT91_H32MX) extern void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, struct at91_pmc *pmc); #endif Index: linux-3.18.13-rt10-r7s4/drivers/clk/clk.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/clk.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/clk.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:357 @ out: mutex_unlock(&clk_debug_lock); } -struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, +struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode, void *data, const struct file_operations *fops) { struct dentry *d = NULL; - if (clk->dentry) - d = debugfs_create_file(name, mode, clk->dentry, data, fops); + if (hw->clk->dentry) + d = debugfs_create_file(name, mode, hw->clk->dentry, data, fops); return d; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:577 @ unsigned int __clk_get_enable_count(stru return !clk ? 0 : clk->enable_count; } -unsigned int __clk_get_prepare_count(struct clk *clk) -{ - return !clk ? 0 : clk->prepare_count; -} - unsigned long __clk_get_rate(struct clk *clk) { unsigned long ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:599 @ out: } EXPORT_SYMBOL_GPL(__clk_get_rate); -unsigned long __clk_get_accuracy(struct clk *clk) +static unsigned long __clk_get_accuracy(struct clk *clk) { if (!clk) return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:705 @ struct clk *__clk_lookup(const char *nam */ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk *clk = hw->clk, *parent, *best_parent = NULL; int i, num_parents; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:741 @ long __clk_mux_determine_rate(struct clk out: if (best_parent) - *best_parent_p = best_parent; + *best_parent_p = best_parent->hw; *best_parent_rate = best; return best; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:949 @ unsigned long __clk_round_rate(struct cl { unsigned long parent_rate = 0; struct clk *parent; + struct clk_hw *parent_hw; if (!clk) return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:958 @ unsigned long __clk_round_rate(struct cl if (parent) parent_rate = parent->rate; - if (clk->ops->determine_rate) + if (clk->ops->determine_rate) { + parent_hw = parent ? parent->hw : NULL; return clk->ops->determine_rate(clk->hw, rate, &parent_rate, - &parent); - else if (clk->ops->round_rate) + &parent_hw); + } else if (clk->ops->round_rate) return clk->ops->round_rate(clk->hw, rate, &parent_rate); else if (clk->flags & CLK_SET_RATE_PARENT) return __clk_round_rate(clk->parent, rate); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1350 @ static struct clk *clk_calc_new_rates(st { struct clk *top = clk; struct clk *old_parent, *parent; + struct clk_hw *parent_hw; unsigned long best_parent_rate = 0; unsigned long new_rate; int p_index = 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1366 @ static struct clk *clk_calc_new_rates(st /* find the closest rate and parent clk/rate */ if (clk->ops->determine_rate) { + parent_hw = parent ? parent->hw : NULL; new_rate = clk->ops->determine_rate(clk->hw, rate, &best_parent_rate, - &parent); + &parent_hw); + parent = parent_hw->clk; } else if (clk->ops->round_rate) { new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1617 @ static struct clk *__clk_init_parent(str if (clk->num_parents == 1) { if (IS_ERR_OR_NULL(clk->parent)) - ret = clk->parent = __clk_lookup(clk->parent_names[0]); + clk->parent = __clk_lookup(clk->parent_names[0]); ret = clk->parent; goto out; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2276 @ int __clk_get(struct clk *clk) void __clk_put(struct clk *clk) { + struct module *owner; + if (!clk || WARN_ON_ONCE(IS_ERR(clk))) return; clk_prepare_lock(); + owner = clk->owner; kref_put(&clk->ref, __clk_release); clk_prepare_unlock(); - module_put(clk->owner); + module_put(owner); } /*** clk rate change notifiers ***/ Index: linux-3.18.13-rt10-r7s4/drivers/clk/clk-composite.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/clk-composite.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/clk-composite.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ static unsigned long clk_composite_recal static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk_composite *composite = to_clk_composite(hw); const struct clk_ops *rate_ops = composite->rate_ops; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:83 @ static long clk_composite_determine_rate *best_parent_p = NULL; if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) { - *best_parent_p = clk_get_parent(mux_hw->clk); - *best_parent_rate = __clk_get_rate(*best_parent_p); + parent = clk_get_parent(mux_hw->clk); + *best_parent_p = __clk_get_hw(parent); + *best_parent_rate = __clk_get_rate(parent); return rate_ops->round_rate(rate_hw, rate, best_parent_rate); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:107 @ static long clk_composite_determine_rate if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) { - *best_parent_p = parent; + *best_parent_p = __clk_get_hw(parent); *best_parent_rate = parent_rate; best_rate_diff = rate_diff; best_rate = tmp_rate; Index: linux-3.18.13-rt10-r7s4/drivers/clk/clk-mux.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clk/clk-mux.c +++ linux-3.18.13-rt10-r7s4/drivers/clk/clk-mux.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:80 @ static int clk_mux_set_parent(struct clk else { if (mux->flags & CLK_MUX_INDEX_BIT) - index = (1 << ffs(index)); + index = 1 << index; if (mux->flags & CLK_MUX_INDEX_ONE) index++; Index: linux-3.18.13-rt10-r7s4/drivers/clocksource/timer-atmel-pit.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/clocksource/timer-atmel-pit.c +++ linux-3.18.13-rt10-r7s4/drivers/clocksource/timer-atmel-pit.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:265 @ static void __init at91sam926x_pit_dt_in } CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", at91sam926x_pit_dt_init); - -static void __iomem *pit_base_addr; - -void __init at91sam926x_pit_init(int irq) -{ - struct pit_data *data; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - panic(pr_fmt("Unable to allocate memory\n")); - - data->base = pit_base_addr; - - data->mck = clk_get(NULL, "mck"); - if (IS_ERR(data->mck)) - panic(pr_fmt("Unable to get mck clk\n")); - - data->irq = irq; - - at91sam926x_pit_common_init(data); -} - -void __init at91sam926x_ioremap_pit(u32 addr) -{ - if (of_have_populated_dt()) - return; - - pit_base_addr = ioremap(addr, 16); - - if (!pit_base_addr) - panic(pr_fmt("Impossible to ioremap PIT\n")); -} Index: linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-aes.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/crypto/atmel-aes.c +++ linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-aes.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:318 @ static int atmel_aes_crypt_dma(struct at dd->dma_size = length; - if (!(dd->flags & AES_FLAGS_FAST)) { - dma_sync_single_for_device(dd->dev, dma_addr_in, length, - DMA_TO_DEVICE); - } + dma_sync_single_for_device(dd->dev, dma_addr_in, length, + DMA_TO_DEVICE); + dma_sync_single_for_device(dd->dev, dma_addr_out, length, + DMA_FROM_DEVICE); if (dd->flags & AES_FLAGS_CFB8) { dd->dma_lch_in.dma_conf.dst_addr_width = @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:394 @ static int atmel_aes_crypt_cpu_start(str { dd->flags &= ~AES_FLAGS_DMA; + dma_sync_single_for_cpu(dd->dev, dd->dma_addr_in, + dd->dma_size, DMA_TO_DEVICE); + dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out, + dd->dma_size, DMA_FROM_DEVICE); + /* use cache buffers */ dd->nb_in_sg = atmel_aes_sg_length(dd->req, dd->in_sg); if (!dd->nb_in_sg) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:467 @ static int atmel_aes_crypt_dma_start(str dd->flags |= AES_FLAGS_FAST; } else { + dma_sync_single_for_cpu(dd->dev, dd->dma_addr_in, + dd->dma_size, DMA_TO_DEVICE); + /* use cache buffers */ count = atmel_aes_sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in, dd->buflen, dd->total, 0); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:630 @ static int atmel_aes_crypt_dma_stop(stru dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); } else { - dma_sync_single_for_device(dd->dev, dd->dma_addr_out, + dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out, dd->dma_size, DMA_FROM_DEVICE); /* copy data */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1257 @ static void atmel_aes_get_cap(struct atm /* keep only major version number */ switch (dd->hw_version & 0xff0) { + case 0x200: + dd->caps.has_dualbuff = 1; + dd->caps.has_cfb64 = 1; + dd->caps.max_burst_size = 4; + break; case 0x130: dd->caps.has_dualbuff = 1; dd->caps.has_cfb64 = 1; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1352 @ static int atmel_aes_probe(struct platfo platform_set_drvdata(pdev, aes_dd); INIT_LIST_HEAD(&aes_dd->list); + spin_lock_init(&aes_dd->lock); tasklet_init(&aes_dd->done_task, atmel_aes_done_task, (unsigned long)aes_dd); Index: linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-sha.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/crypto/atmel-sha.c +++ linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-sha.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:170 @ static size_t atmel_sha_append_sg(struct count = min(ctx->sg->length - ctx->offset, ctx->total); count = min(count, ctx->buflen - ctx->bufcnt); - if (count <= 0) - break; + if (count <= 0) { + /* + * Check if count <= 0 because the buffer is full or + * because the sg length is 0. In the latest case, + * check if there is another sg in the list, a 0 length + * sg doesn't necessarily mean the end of the sg list. + */ + if ((ctx->sg->length == 0) && !sg_is_last(ctx->sg)) { + ctx->sg = sg_next(ctx->sg); + continue; + } else + break; + } scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, ctx->sg, ctx->offset, count, 0); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:438 @ static int atmel_sha_xmit_dma(struct atm dev_dbg(dd->dev, "xmit_dma: digcnt: 0x%llx 0x%llx, length: %d, final: %d\n", ctx->digcnt[1], ctx->digcnt[0], length1, final); - if (ctx->flags & (SHA_FLAGS_SHA1 | SHA_FLAGS_SHA224 | - SHA_FLAGS_SHA256)) { - dd->dma_lch_in.dma_conf.src_maxburst = 16; - dd->dma_lch_in.dma_conf.dst_maxburst = 16; - } else { - dd->dma_lch_in.dma_conf.src_maxburst = 32; - dd->dma_lch_in.dma_conf.dst_maxburst = 32; - } + dd->dma_lch_in.dma_conf.src_maxburst = 16; + dd->dma_lch_in.dma_conf.dst_maxburst = 16; dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:541 @ static int atmel_sha_update_dma_slow(str if (final) atmel_sha_fill_padding(ctx, 0); - if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) { + if (final || (ctx->bufcnt == ctx->buflen)) { count = ctx->bufcnt; ctx->bufcnt = 0; return atmel_sha_xmit_dma_map(dd, ctx, count, final); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1312 @ static void atmel_sha_get_cap(struct atm /* keep only major version number */ switch (dd->hw_version & 0xff0) { + case 0x420: + dd->caps.has_dma = 1; + dd->caps.has_dualbuff = 1; + dd->caps.has_sha224 = 1; + dd->caps.has_sha_384_512 = 1; + break; case 0x410: dd->caps.has_dma = 1; dd->caps.has_dualbuff = 1; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1401 @ static int atmel_sha_probe(struct platfo platform_set_drvdata(pdev, sha_dd); INIT_LIST_HEAD(&sha_dd->list); + spin_lock_init(&sha_dd->lock); tasklet_init(&sha_dd->done_task, atmel_sha_done_task, (unsigned long)sha_dd); Index: linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-tdes.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/crypto/atmel-tdes.c +++ linux-3.18.13-rt10-r7s4/drivers/crypto/atmel-tdes.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1373 @ static int atmel_tdes_probe(struct platf platform_set_drvdata(pdev, tdes_dd); INIT_LIST_HEAD(&tdes_dd->list); + spin_lock_init(&tdes_dd->lock); tasklet_init(&tdes_dd->done_task, atmel_tdes_done_task, (unsigned long)tdes_dd); Index: linux-3.18.13-rt10-r7s4/drivers/dma/at_hdmac.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/at_hdmac.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/at_hdmac.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:45 @ #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) #define ATC_DEFAULT_CTRLB (ATC_SIF(AT_DMA_MEM_IF) \ |ATC_DIF(AT_DMA_MEM_IF)) +#define ATC_DMA_BUSWIDTHS\ + (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) /* * Initial number of descriptors to allocate for each channel. This could @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:68 @ static void atc_issue_pending(struct dma /*----------------------------------------------------------------------*/ +static inline unsigned int atc_get_xfer_width(dma_addr_t src, dma_addr_t dst, + size_t len) +{ + unsigned int width; + + if (!((src | dst | len) & 3)) + width = 2; + else if (!((src | dst | len) & 1)) + width = 1; + else + width = 0; + + return width; +} + static struct at_desc *atc_first_active(struct at_dma_chan *atchan) { return list_first_entry(&atchan->active_list, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:256 @ static void atc_dostart(struct at_dma_ch } /* - * atc_get_current_descriptors - - * locate the descriptor which equal to physical address in DSCR - * @atchan: the channel we want to start - * @dscr_addr: physical descriptor address in DSCR + * atc_get_desc_by_cookie - get the descriptor of a cookie + * @atchan: the DMA channel + * @cookie: the cookie to get the descriptor for */ -static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan, - u32 dscr_addr) +static struct at_desc *atc_get_desc_by_cookie(struct at_dma_chan *atchan, + dma_cookie_t cookie) { - struct at_desc *desc, *_desc, *child, *desc_cur = NULL; + struct at_desc *desc, *_desc; - list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) { - if (desc->lli.dscr == dscr_addr) { - desc_cur = desc; - break; - } + list_for_each_entry_safe(desc, _desc, &atchan->queue, desc_node) { + if (desc->txd.cookie == cookie) + return desc; + } - list_for_each_entry(child, &desc->tx_list, desc_node) { - if (child->lli.dscr == dscr_addr) { - desc_cur = child; - break; - } - } + list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) { + if (desc->txd.cookie == cookie) + return desc; } - return desc_cur; + return NULL; } -/* - * atc_get_bytes_left - - * Get the number of bytes residue in dma buffer, - * @chan: the channel we want to start +/** + * atc_calc_bytes_left - calculates the number of bytes left according to the + * value read from CTRLA. + * + * @current_len: the number of bytes left before reading CTRLA + * @ctrla: the value of CTRLA + * @desc: the descriptor containing the transfer width */ -static int atc_get_bytes_left(struct dma_chan *chan) +static inline int atc_calc_bytes_left(int current_len, u32 ctrla, + struct at_desc *desc) +{ + return current_len - ((ctrla & ATC_BTSIZE_MAX) << desc->tx_width); +} + +/** + * atc_calc_bytes_left_from_reg - calculates the number of bytes left according + * to the current value of CTRLA. + * + * @current_len: the number of bytes left before reading CTRLA + * @atchan: the channel to read CTRLA for + * @desc: the descriptor containing the transfer width + */ +static inline int atc_calc_bytes_left_from_reg(int current_len, + struct at_dma_chan *atchan, struct at_desc *desc) +{ + u32 ctrla = channel_readl(atchan, CTRLA); + + return atc_calc_bytes_left(current_len, ctrla, desc); +} + +/** + * atc_get_bytes_left - get the number of bytes residue for a cookie + * @chan: DMA channel + * @cookie: transaction identifier to check status of + */ +static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie) { struct at_dma_chan *atchan = to_at_dma_chan(chan); - struct at_dma *atdma = to_at_dma(chan->device); - int chan_id = atchan->chan_common.chan_id; struct at_desc *desc_first = atc_first_active(atchan); - struct at_desc *desc_cur; - int ret = 0, count = 0; + struct at_desc *desc; + int ret; + u32 ctrla, dscr; /* - * Initialize necessary values in the first time. - * remain_desc record remain desc length. + * If the cookie doesn't match to the currently running transfer then + * we can return the total length of the associated DMA transfer, + * because it is still queued. */ - if (atchan->remain_desc == 0) - /* First descriptor embedds the transaction length */ - atchan->remain_desc = desc_first->len; + desc = atc_get_desc_by_cookie(atchan, cookie); + if (desc == NULL) + return -EINVAL; + else if (desc != desc_first) + return desc->total_len; - /* - * This happens when current descriptor transfer complete. - * The residual buffer size should reduce current descriptor length. - */ - if (unlikely(test_bit(ATC_IS_BTC, &atchan->status))) { - clear_bit(ATC_IS_BTC, &atchan->status); - desc_cur = atc_get_current_descriptors(atchan, - channel_readl(atchan, DSCR)); - if (!desc_cur) { - ret = -EINVAL; - goto out; - } + /* cookie matches to the currently running transfer */ + ret = desc_first->total_len; + + if (desc_first->lli.dscr) { + /* hardware linked list transfer */ + + /* + * Calculate the residue by removing the length of the child + * descriptors already transferred from the total length. + * To get the current child descriptor we can use the value of + * the channel's DSCR register and compare it against the value + * of the hardware linked list structure of each child + * descriptor. + */ - count = (desc_cur->lli.ctrla & ATC_BTSIZE_MAX) - << desc_first->tx_width; - if (atchan->remain_desc < count) { - ret = -EINVAL; - goto out; + ctrla = channel_readl(atchan, CTRLA); + rmb(); /* ensure CTRLA is read before DSCR */ + dscr = channel_readl(atchan, DSCR); + + /* for the first descriptor we can be more accurate */ + if (desc_first->lli.dscr == dscr) + return atc_calc_bytes_left(ret, ctrla, desc_first); + + ret -= desc_first->len; + list_for_each_entry(desc, &desc_first->tx_list, desc_node) { + if (desc->lli.dscr == dscr) + break; + + ret -= desc->len; } - atchan->remain_desc -= count; - ret = atchan->remain_desc; - } else { /* - * Get residual bytes when current - * descriptor transfer in progress. + * For the last descriptor in the chain we can calculate + * the remaining bytes using the channel's register. + * Note that the transfer width of the first and last + * descriptor may differ. */ - count = (channel_readl(atchan, CTRLA) & ATC_BTSIZE_MAX) - << (desc_first->tx_width); - ret = atchan->remain_desc - count; + if (!desc->lli.dscr) + ret = atc_calc_bytes_left_from_reg(ret, atchan, desc); + } else { + /* single transfer */ + ret = atc_calc_bytes_left_from_reg(ret, atchan, desc_first); } - /* - * Check fifo empty. - */ - if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id))) - atc_issue_pending(chan); -out: return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:590 @ static irqreturn_t at_dma_interrupt(int /* Give information to tasklet */ set_bit(ATC_IS_ERROR, &atchan->status); } - if (pending & AT_DMA_BTC(i)) - set_bit(ATC_IS_BTC, &atchan->status); tasklet_schedule(&atchan->tasklet); ret = IRQ_HANDLED; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:677 @ atc_prep_dma_memcpy(struct dma_chan *cha * We can be a lot more clever here, but this should take care * of the most common optimization. */ - if (!((src | dest | len) & 3)) { - ctrla = ATC_SRC_WIDTH_WORD | ATC_DST_WIDTH_WORD; - src_width = dst_width = 2; - } else if (!((src | dest | len) & 1)) { - ctrla = ATC_SRC_WIDTH_HALFWORD | ATC_DST_WIDTH_HALFWORD; - src_width = dst_width = 1; - } else { - ctrla = ATC_SRC_WIDTH_BYTE | ATC_DST_WIDTH_BYTE; - src_width = dst_width = 0; - } + src_width = dst_width = atc_get_xfer_width(src, dest, len); + + ctrla = ATC_SRC_WIDTH(src_width) | + ATC_DST_WIDTH(dst_width); for (offset = 0; offset < len; offset += xfer_count << src_width) { xfer_count = min_t(size_t, (len - offset) >> src_width, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:696 @ atc_prep_dma_memcpy(struct dma_chan *cha desc->lli.ctrlb = ctrlb; desc->txd.cookie = 0; + desc->len = xfer_count << src_width; atc_desc_chain(&first, &prev, desc); } /* First descriptor of the chain embedds additional information */ first->txd.cookie = -EBUSY; - first->len = len; + first->total_len = len; + + /* set transfer width for the calculation of the residue */ first->tx_width = src_width; + prev->tx_width = src_width; /* set end-of-link to the last link descriptor of list*/ set_desc_eol(desc); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:799 @ atc_prep_slave_sg(struct dma_chan *chan, | ATC_SRC_WIDTH(mem_width) | len >> mem_width; desc->lli.ctrlb = ctrlb; + desc->len = len; atc_desc_chain(&first, &prev, desc); total_len += len; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:840 @ atc_prep_slave_sg(struct dma_chan *chan, | ATC_DST_WIDTH(mem_width) | len >> reg_width; desc->lli.ctrlb = ctrlb; + desc->len = len; atc_desc_chain(&first, &prev, desc); total_len += len; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:855 @ atc_prep_slave_sg(struct dma_chan *chan, /* First descriptor of the chain embedds additional information */ first->txd.cookie = -EBUSY; - first->len = total_len; + first->total_len = total_len; + + /* set transfer width for the calculation of the residue */ first->tx_width = reg_width; + prev->tx_width = reg_width; /* first link descriptor of list is responsible of flags */ first->txd.flags = flags; /* client is in control of this ack */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:874 @ err: } /** + * atc_prep_dma_sg - prepare memory to memory scather-gather operation + * @chan: the channel to prepare operation on + * @dst_sg: destination scatterlist + * @dst_nents: number of destination scatterlist entries + * @src_sg: source scatterlist + * @src_nents: number of source scatterlist entries + * @flags: tx descriptor status flags + */ +static struct dma_async_tx_descriptor * +atc_prep_dma_sg(struct dma_chan *chan, + struct scatterlist *dst_sg, unsigned int dst_nents, + struct scatterlist *src_sg, unsigned int src_nents, + unsigned long flags) +{ + struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_desc *desc = NULL; + struct at_desc *first = NULL; + struct at_desc *prev = NULL; + unsigned int src_width; + unsigned int dst_width; + size_t xfer_count; + u32 ctrla; + u32 ctrlb; + size_t dst_len = 0, src_len = 0; + dma_addr_t dst = 0, src = 0; + size_t len = 0, total_len = 0; + + if (unlikely(dst_nents == 0 || src_nents == 0)) + return NULL; + + if (unlikely(dst_sg == NULL || src_sg == NULL)) + return NULL; + + ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN + | ATC_SRC_ADDR_MODE_INCR + | ATC_DST_ADDR_MODE_INCR + | ATC_FC_MEM2MEM; + + /* + * loop until there is either no more source or no more destination + * scatterlist entry + */ + while (true) { + + /* prepare the next transfer */ + if (dst_len == 0) { + + /* no more destination scatterlist entries */ + if (!dst_sg || !dst_nents) + break; + + dst = sg_dma_address(dst_sg); + dst_len = sg_dma_len(dst_sg); + + dst_sg = sg_next(dst_sg); + dst_nents--; + } + + if (src_len == 0) { + + /* no more source scatterlist entries */ + if (!src_sg || !src_nents) + break; + + src = sg_dma_address(src_sg); + src_len = sg_dma_len(src_sg); + + src_sg = sg_next(src_sg); + src_nents--; + } + + len = min_t(size_t, src_len, dst_len); + if (len == 0) + continue; + + /* take care for the alignment */ + src_width = dst_width = atc_get_xfer_width(src, dst, len); + + ctrla = ATC_SRC_WIDTH(src_width) | + ATC_DST_WIDTH(dst_width); + + /* + * The number of transfers to set up refer to the source width + * that depends on the alignment. + */ + xfer_count = len >> src_width; + if (xfer_count > ATC_BTSIZE_MAX) { + xfer_count = ATC_BTSIZE_MAX; + len = ATC_BTSIZE_MAX << src_width; + } + + /* create the transfer */ + desc = atc_desc_get(atchan); + if (!desc) + goto err_desc_get; + + desc->lli.saddr = src; + desc->lli.daddr = dst; + desc->lli.ctrla = ctrla | xfer_count; + desc->lli.ctrlb = ctrlb; + + desc->txd.cookie = 0; + desc->len = len; + + /* + * Although we only need the transfer width for the first and + * the last descriptor, its easier to set it to all descriptors. + */ + desc->tx_width = src_width; + + atc_desc_chain(&first, &prev, desc); + + /* update the lengths and addresses for the next loop cycle */ + dst_len -= len; + src_len -= len; + dst += len; + src += len; + + total_len += len; + } + + /* First descriptor of the chain embedds additional information */ + first->txd.cookie = -EBUSY; + first->total_len = total_len; + + /* set end-of-link to the last link descriptor of list*/ + set_desc_eol(desc); + + first->txd.flags = flags; /* client is in control of this ack */ + + return &first->txd; + +err_desc_get: + atc_desc_put(atchan, first); + return NULL; +} + +/** * atc_dma_cyclic_check_values * Check for too big/unaligned periods and unaligned DMA buffer */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1062 @ atc_dma_cyclic_fill_desc(struct dma_chan | ATC_FC_MEM2PER | ATC_SIF(atchan->mem_if) | ATC_DIF(atchan->per_if); + desc->len = period_len; break; case DMA_DEV_TO_MEM: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1074 @ atc_dma_cyclic_fill_desc(struct dma_chan | ATC_FC_PER2MEM | ATC_SIF(atchan->per_if) | ATC_DIF(atchan->mem_if); + desc->len = period_len; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1156 @ atc_prep_dma_cyclic(struct dma_chan *cha /* First descriptor of the chain embedds additional information */ first->txd.cookie = -EBUSY; - first->len = buf_len; + first->total_len = buf_len; first->tx_width = reg_width; return &first->txd; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1169 @ err_out: return NULL; } -static int set_runtime_config(struct dma_chan *chan, - struct dma_slave_config *sconfig) +static int atc_config(struct dma_chan *chan, + struct dma_slave_config *sconfig) { struct at_dma_chan *atchan = to_at_dma_chan(chan); + dev_vdbg(chan2dev(chan), "%s\n", __func__); + /* Check if it is chan is configured for slave transfers */ if (!chan->private) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1188 @ static int set_runtime_config(struct dma return 0; } +static int atc_pause(struct dma_chan *chan) +{ + struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_dma *atdma = to_at_dma(chan->device); + int chan_id = atchan->chan_common.chan_id; + unsigned long flags; + + LIST_HEAD(list); -static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, - unsigned long arg) + dev_vdbg(chan2dev(chan), "%s\n", __func__); + + spin_lock_irqsave(&atchan->lock, flags); + + dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id)); + set_bit(ATC_IS_PAUSED, &atchan->status); + + spin_unlock_irqrestore(&atchan->lock, flags); + + return 0; +} + +static int atc_resume(struct dma_chan *chan) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1218 @ static int atc_control(struct dma_chan * LIST_HEAD(list); - dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd); + dev_vdbg(chan2dev(chan), "%s\n", __func__); - if (cmd == DMA_PAUSE) { - spin_lock_irqsave(&atchan->lock, flags); + if (!atc_chan_is_paused(atchan)) + return 0; - dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id)); - set_bit(ATC_IS_PAUSED, &atchan->status); + spin_lock_irqsave(&atchan->lock, flags); - spin_unlock_irqrestore(&atchan->lock, flags); - } else if (cmd == DMA_RESUME) { - if (!atc_chan_is_paused(atchan)) - return 0; + dma_writel(atdma, CHDR, AT_DMA_RES(chan_id)); + clear_bit(ATC_IS_PAUSED, &atchan->status); - spin_lock_irqsave(&atchan->lock, flags); + spin_unlock_irqrestore(&atchan->lock, flags); - dma_writel(atdma, CHDR, AT_DMA_RES(chan_id)); - clear_bit(ATC_IS_PAUSED, &atchan->status); + return 0; +} - spin_unlock_irqrestore(&atchan->lock, flags); - } else if (cmd == DMA_TERMINATE_ALL) { - struct at_desc *desc, *_desc; - /* - * This is only called when something went wrong elsewhere, so - * we don't really care about the data. Just disable the - * channel. We still have to poll the channel enable bit due - * to AHB/HSB limitations. - */ - spin_lock_irqsave(&atchan->lock, flags); +static int atc_terminate_all(struct dma_chan *chan) +{ + struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_dma *atdma = to_at_dma(chan->device); + int chan_id = atchan->chan_common.chan_id; + struct at_desc *desc, *_desc; + unsigned long flags; - /* disabling channel: must also remove suspend state */ - dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask); + LIST_HEAD(list); - /* confirm that this channel is disabled */ - while (dma_readl(atdma, CHSR) & atchan->mask) - cpu_relax(); - - /* active_list entries will end up before queued entries */ - list_splice_init(&atchan->queue, &list); - list_splice_init(&atchan->active_list, &list); - - /* Flush all pending and queued descriptors */ - list_for_each_entry_safe(desc, _desc, &list, desc_node) - atc_chain_complete(atchan, desc); - - clear_bit(ATC_IS_PAUSED, &atchan->status); - /* if channel dedicated to cyclic operations, free it */ - clear_bit(ATC_IS_CYCLIC, &atchan->status); + dev_vdbg(chan2dev(chan), "%s\n", __func__); - spin_unlock_irqrestore(&atchan->lock, flags); - } else if (cmd == DMA_SLAVE_CONFIG) { - return set_runtime_config(chan, (struct dma_slave_config *)arg); - } else { - return -ENXIO; - } + /* + * This is only called when something went wrong elsewhere, so + * we don't really care about the data. Just disable the + * channel. We still have to poll the channel enable bit due + * to AHB/HSB limitations. + */ + spin_lock_irqsave(&atchan->lock, flags); + + /* disabling channel: must also remove suspend state */ + dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask); + + /* confirm that this channel is disabled */ + while (dma_readl(atdma, CHSR) & atchan->mask) + cpu_relax(); + + /* active_list entries will end up before queued entries */ + list_splice_init(&atchan->queue, &list); + list_splice_init(&atchan->active_list, &list); + + /* Flush all pending and queued descriptors */ + list_for_each_entry_safe(desc, _desc, &list, desc_node) + atc_chain_complete(atchan, desc); + + clear_bit(ATC_IS_PAUSED, &atchan->status); + /* if channel dedicated to cyclic operations, free it */ + clear_bit(ATC_IS_CYCLIC, &atchan->status); + + spin_unlock_irqrestore(&atchan->lock, flags); return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1310 @ atc_tx_status(struct dma_chan *chan, spin_lock_irqsave(&atchan->lock, flags); /* Get number of bytes left in the active transactions */ - bytes = atc_get_bytes_left(chan); + bytes = atc_get_bytes_left(chan, cookie); spin_unlock_irqrestore(&atchan->lock, flags); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1406 @ static int atc_alloc_chan_resources(stru spin_lock_irqsave(&atchan->lock, flags); atchan->descs_allocated = i; - atchan->remain_desc = 0; list_splice(&tmp_list, &atchan->free_list); dma_cookie_init(chan); spin_unlock_irqrestore(&atchan->lock, flags); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1448 @ static void atc_free_chan_resources(stru list_splice_init(&atchan->free_list, &list); atchan->descs_allocated = 0; atchan->status = 0; - atchan->remain_desc = 0; dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1611 @ static int __init at_dma_probe(struct pl /* setup platform data for each SoC */ dma_cap_set(DMA_MEMCPY, at91sam9rl_config.cap_mask); + dma_cap_set(DMA_SG, at91sam9rl_config.cap_mask); dma_cap_set(DMA_MEMCPY, at91sam9g45_config.cap_mask); dma_cap_set(DMA_SLAVE, at91sam9g45_config.cap_mask); + dma_cap_set(DMA_SG, at91sam9g45_config.cap_mask); /* get DMA parameters from controller type */ plat_dat = at_dma_get_driver_data(pdev); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1724 @ static int __init at_dma_probe(struct pl /* controller can do slave DMA: can trigger cyclic transfers */ dma_cap_set(DMA_CYCLIC, atdma->dma_common.cap_mask); atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic; - atdma->dma_common.device_control = atc_control; + atdma->dma_common.device_config = atc_config; + atdma->dma_common.device_pause = atc_pause; + atdma->dma_common.device_resume = atc_resume; + atdma->dma_common.device_terminate_all = atc_terminate_all; + atdma->dma_common.src_addr_widths = ATC_DMA_BUSWIDTHS; + atdma->dma_common.dst_addr_widths = ATC_DMA_BUSWIDTHS; + atdma->dma_common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + atdma->dma_common.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; } + if (dma_has_cap(DMA_SG, atdma->dma_common.cap_mask)) + atdma->dma_common.device_prep_dma_sg = atc_prep_dma_sg; + dma_writel(atdma, EN, AT_DMA_ENABLE); - dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n", + dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s%s), %d channels\n", dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "", dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", + dma_has_cap(DMA_SG, atdma->dma_common.cap_mask) ? "sg-cpy " : "", plat_dat->nr_channels); dma_async_device_register(&atdma->dma_common); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1852 @ static void atc_suspend_cyclic(struct at if (!atc_chan_is_paused(atchan)) { dev_warn(chan2dev(chan), "cyclic channel not paused, should be done by channel user\n"); - atc_control(chan, DMA_PAUSE, 0); + atc_pause(chan); } /* now preserve additional data for cyclic operations */ Index: linux-3.18.13-rt10-r7s4/drivers/dma/at_hdmac_regs.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/at_hdmac_regs.h +++ linux-3.18.13-rt10-r7s4/drivers/dma/at_hdmac_regs.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:184 @ struct at_lli { * @at_lli: hardware lli structure * @txd: support for the async_tx api * @desc_node: node on the channed descriptors list - * @len: total transaction bytecount + * @len: descriptor byte count * @tx_width: transfer width + * @total_len: total transaction byte count */ struct at_desc { /* FIRST values the hardware uses */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:198 @ struct at_desc { struct list_head desc_node; size_t len; u32 tx_width; + size_t total_len; }; static inline struct at_desc * @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:218 @ txd_to_at_desc(struct dma_async_tx_descr enum atc_status { ATC_IS_ERROR = 0, ATC_IS_PAUSED = 1, - ATC_IS_BTC = 2, ATC_IS_CYCLIC = 24, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:235 @ enum atc_status { * @save_cfg: configuration register that is saved on suspend/resume cycle * @save_dscr: for cyclic operations, preserve next descriptor address in * the cyclic list on suspend/resume cycle - * @remain_desc: to save remain desc length * @dma_sconfig: configuration for slave transfers, passed via DMA_SLAVE_CONFIG * @lock: serializes enqueue/dequeue operations to descriptors lists * @active_list: list of descriptors dmaengine is being running on @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:253 @ struct at_dma_chan { struct tasklet_struct tasklet; u32 save_cfg; u32 save_dscr; - u32 remain_desc; struct dma_slave_config dma_sconfig; spinlock_t lock; Index: linux-3.18.13-rt10-r7s4/drivers/dma/at_xdmac.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/dma/at_xdmac.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Driver for the Atmel Extensible DMA Controller (aka XDMAC on AT91 systems) + * + * Copyright (C) 2014 Atmel Corporation + * + * Author: Ludovic Desroches <ludovic.desroches@atmel.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <asm/barrier.h> +#include <dt-bindings/dma/at91.h> +#include <linux/clk.h> +#include <linux/dmaengine.h> +#include <linux/dmapool.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/of_dma.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/pm.h> + +#include "dmaengine.h" + +/* Global registers */ +#define AT_XDMAC_GTYPE 0x00 /* Global Type Register */ +#define AT_XDMAC_NB_CH(i) (((i) & 0x1F) + 1) /* Number of Channels Minus One */ +#define AT_XDMAC_FIFO_SZ(i) (((i) >> 5) & 0x7FF) /* Number of Bytes */ +#define AT_XDMAC_NB_REQ(i) ((((i) >> 16) & 0x3F) + 1) /* Number of Peripheral Requests Minus One */ +#define AT_XDMAC_GCFG 0x04 /* Global Configuration Register */ +#define AT_XDMAC_GWAC 0x08 /* Global Weighted Arbiter Configuration Register */ +#define AT_XDMAC_GIE 0x0C /* Global Interrupt Enable Register */ +#define AT_XDMAC_GID 0x10 /* Global Interrupt Disable Register */ +#define AT_XDMAC_GIM 0x14 /* Global Interrupt Mask Register */ +#define AT_XDMAC_GIS 0x18 /* Global Interrupt Status Register */ +#define AT_XDMAC_GE 0x1C /* Global Channel Enable Register */ +#define AT_XDMAC_GD 0x20 /* Global Channel Disable Register */ +#define AT_XDMAC_GS 0x24 /* Global Channel Status Register */ +#define AT_XDMAC_GRS 0x28 /* Global Channel Read Suspend Register */ +#define AT_XDMAC_GWS 0x2C /* Global Write Suspend Register */ +#define AT_XDMAC_GRWS 0x30 /* Global Channel Read Write Suspend Register */ +#define AT_XDMAC_GRWR 0x34 /* Global Channel Read Write Resume Register */ +#define AT_XDMAC_GSWR 0x38 /* Global Channel Software Request Register */ +#define AT_XDMAC_GSWS 0x3C /* Global channel Software Request Status Register */ +#define AT_XDMAC_GSWF 0x40 /* Global Channel Software Flush Request Register */ +#define AT_XDMAC_VERSION 0xFFC /* XDMAC Version Register */ + +/* Channel relative registers offsets */ +#define AT_XDMAC_CIE 0x00 /* Channel Interrupt Enable Register */ +#define AT_XDMAC_CIE_BIE BIT(0) /* End of Block Interrupt Enable Bit */ +#define AT_XDMAC_CIE_LIE BIT(1) /* End of Linked List Interrupt Enable Bit */ +#define AT_XDMAC_CIE_DIE BIT(2) /* End of Disable Interrupt Enable Bit */ +#define AT_XDMAC_CIE_FIE BIT(3) /* End of Flush Interrupt Enable Bit */ +#define AT_XDMAC_CIE_RBEIE BIT(4) /* Read Bus Error Interrupt Enable Bit */ +#define AT_XDMAC_CIE_WBEIE BIT(5) /* Write Bus Error Interrupt Enable Bit */ +#define AT_XDMAC_CIE_ROIE BIT(6) /* Request Overflow Interrupt Enable Bit */ +#define AT_XDMAC_CID 0x04 /* Channel Interrupt Disable Register */ +#define AT_XDMAC_CID_BID BIT(0) /* End of Block Interrupt Disable Bit */ +#define AT_XDMAC_CID_LID BIT(1) /* End of Linked List Interrupt Disable Bit */ +#define AT_XDMAC_CID_DID BIT(2) /* End of Disable Interrupt Disable Bit */ +#define AT_XDMAC_CID_FID BIT(3) /* End of Flush Interrupt Disable Bit */ +#define AT_XDMAC_CID_RBEID BIT(4) /* Read Bus Error Interrupt Disable Bit */ +#define AT_XDMAC_CID_WBEID BIT(5) /* Write Bus Error Interrupt Disable Bit */ +#define AT_XDMAC_CID_ROID BIT(6) /* Request Overflow Interrupt Disable Bit */ +#define AT_XDMAC_CIM 0x08 /* Channel Interrupt Mask Register */ +#define AT_XDMAC_CIM_BIM BIT(0) /* End of Block Interrupt Mask Bit */ +#define AT_XDMAC_CIM_LIM BIT(1) /* End of Linked List Interrupt Mask Bit */ +#define AT_XDMAC_CIM_DIM BIT(2) /* End of Disable Interrupt Mask Bit */ +#define AT_XDMAC_CIM_FIM BIT(3) /* End of Flush Interrupt Mask Bit */ +#define AT_XDMAC_CIM_RBEIM BIT(4) /* Read Bus Error Interrupt Mask Bit */ +#define AT_XDMAC_CIM_WBEIM BIT(5) /* Write Bus Error Interrupt Mask Bit */ +#define AT_XDMAC_CIM_ROIM BIT(6) /* Request Overflow Interrupt Mask Bit */ +#define AT_XDMAC_CIS 0x0C /* Channel Interrupt Status Register */ +#define AT_XDMAC_CIS_BIS BIT(0) /* End of Block Interrupt Status Bit */ +#define AT_XDMAC_CIS_LIS BIT(1) /* End of Linked List Interrupt Status Bit */ +#define AT_XDMAC_CIS_DIS BIT(2) /* End of Disable Interrupt Status Bit */ +#define AT_XDMAC_CIS_FIS BIT(3) /* End of Flush Interrupt Status Bit */ +#define AT_XDMAC_CIS_RBEIS BIT(4) /* Read Bus Error Interrupt Status Bit */ +#define AT_XDMAC_CIS_WBEIS BIT(5) /* Write Bus Error Interrupt Status Bit */ +#define AT_XDMAC_CIS_ROIS BIT(6) /* Request Overflow Interrupt Status Bit */ +#define AT_XDMAC_CSA 0x10 /* Channel Source Address Register */ +#define AT_XDMAC_CDA 0x14 /* Channel Destination Address Register */ +#define AT_XDMAC_CNDA 0x18 /* Channel Next Descriptor Address Register */ +#define AT_XDMAC_CNDA_NDAIF(i) ((i) & 0x1) /* Channel x Next Descriptor Interface */ +#define AT_XDMAC_CNDA_NDA(i) ((i) & 0xfffffffc) /* Channel x Next Descriptor Address */ +#define AT_XDMAC_CNDC 0x1C /* Channel Next Descriptor Control Register */ +#define AT_XDMAC_CNDC_NDE (0x1 << 0) /* Channel x Next Descriptor Enable */ +#define AT_XDMAC_CNDC_NDSUP (0x1 << 1) /* Channel x Next Descriptor Source Update */ +#define AT_XDMAC_CNDC_NDDUP (0x1 << 2) /* Channel x Next Descriptor Destination Update */ +#define AT_XDMAC_CNDC_NDVIEW_NDV0 (0x0 << 3) /* Channel x Next Descriptor View 0 */ +#define AT_XDMAC_CNDC_NDVIEW_NDV1 (0x1 << 3) /* Channel x Next Descriptor View 1 */ +#define AT_XDMAC_CNDC_NDVIEW_NDV2 (0x2 << 3) /* Channel x Next Descriptor View 2 */ +#define AT_XDMAC_CNDC_NDVIEW_NDV3 (0x3 << 3) /* Channel x Next Descriptor View 3 */ +#define AT_XDMAC_CUBC 0x20 /* Channel Microblock Control Register */ +#define AT_XDMAC_CBC 0x24 /* Channel Block Control Register */ +#define AT_XDMAC_CC 0x28 /* Channel Configuration Register */ +#define AT_XDMAC_CC_TYPE (0x1 << 0) /* Channel Transfer Type */ +#define AT_XDMAC_CC_TYPE_MEM_TRAN (0x0 << 0) /* Memory to Memory Transfer */ +#define AT_XDMAC_CC_TYPE_PER_TRAN (0x1 << 0) /* Peripheral to Memory or Memory to Peripheral Transfer */ +#define AT_XDMAC_CC_MBSIZE_MASK (0x3 << 1) +#define AT_XDMAC_CC_MBSIZE_SINGLE (0x0 << 1) +#define AT_XDMAC_CC_MBSIZE_FOUR (0x1 << 1) +#define AT_XDMAC_CC_MBSIZE_EIGHT (0x2 << 1) +#define AT_XDMAC_CC_MBSIZE_SIXTEEN (0x3 << 1) +#define AT_XDMAC_CC_DSYNC (0x1 << 4) /* Channel Synchronization */ +#define AT_XDMAC_CC_DSYNC_PER2MEM (0x0 << 4) +#define AT_XDMAC_CC_DSYNC_MEM2PER (0x1 << 4) +#define AT_XDMAC_CC_PROT (0x1 << 5) /* Channel Protection */ +#define AT_XDMAC_CC_PROT_SEC (0x0 << 5) +#define AT_XDMAC_CC_PROT_UNSEC (0x1 << 5) +#define AT_XDMAC_CC_SWREQ (0x1 << 6) /* Channel Software Request Trigger */ +#define AT_XDMAC_CC_SWREQ_HWR_CONNECTED (0x0 << 6) +#define AT_XDMAC_CC_SWREQ_SWR_CONNECTED (0x1 << 6) +#define AT_XDMAC_CC_MEMSET (0x1 << 7) /* Channel Fill Block of memory */ +#define AT_XDMAC_CC_MEMSET_NORMAL_MODE (0x0 << 7) +#define AT_XDMAC_CC_MEMSET_HW_MODE (0x1 << 7) +#define AT_XDMAC_CC_CSIZE(i) ((0x7 & (i)) << 8) /* Channel Chunk Size */ +#define AT_XDMAC_CC_DWIDTH_OFFSET 11 +#define AT_XDMAC_CC_DWIDTH_MASK (0x3 << AT_XDMAC_CC_DWIDTH_OFFSET) +#define AT_XDMAC_CC_DWIDTH(i) ((0x3 & (i)) << AT_XDMAC_CC_DWIDTH_OFFSET) /* Channel Data Width */ +#define AT_XDMAC_CC_DWIDTH_BYTE 0x0 +#define AT_XDMAC_CC_DWIDTH_HALFWORD 0x1 +#define AT_XDMAC_CC_DWIDTH_WORD 0x2 +#define AT_XDMAC_CC_DWIDTH_DWORD 0x3 +#define AT_XDMAC_CC_SIF(i) ((0x1 & (i)) << 13) /* Channel Source Interface Identifier */ +#define AT_XDMAC_CC_DIF(i) ((0x1 & (i)) << 14) /* Channel Destination Interface Identifier */ +#define AT_XDMAC_CC_SAM_MASK (0x3 << 16) /* Channel Source Addressing Mode */ +#define AT_XDMAC_CC_SAM_FIXED_AM (0x0 << 16) +#define AT_XDMAC_CC_SAM_INCREMENTED_AM (0x1 << 16) +#define AT_XDMAC_CC_SAM_UBS_AM (0x2 << 16) +#define AT_XDMAC_CC_SAM_UBS_DS_AM (0x3 << 16) +#define AT_XDMAC_CC_DAM_MASK (0x3 << 18) /* Channel Source Addressing Mode */ +#define AT_XDMAC_CC_DAM_FIXED_AM (0x0 << 18) +#define AT_XDMAC_CC_DAM_INCREMENTED_AM (0x1 << 18) +#define AT_XDMAC_CC_DAM_UBS_AM (0x2 << 18) +#define AT_XDMAC_CC_DAM_UBS_DS_AM (0x3 << 18) +#define AT_XDMAC_CC_INITD (0x1 << 21) /* Channel Initialization Terminated (read only) */ +#define AT_XDMAC_CC_INITD_TERMINATED (0x0 << 21) +#define AT_XDMAC_CC_INITD_IN_PROGRESS (0x1 << 21) +#define AT_XDMAC_CC_RDIP (0x1 << 22) /* Read in Progress (read only) */ +#define AT_XDMAC_CC_RDIP_DONE (0x0 << 22) +#define AT_XDMAC_CC_RDIP_IN_PROGRESS (0x1 << 22) +#define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */ +#define AT_XDMAC_CC_WRIP_DONE (0x0 << 23) +#define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23) +#define AT_XDMAC_CC_PERID(i) (0x7f & (h) << 24) /* Channel Peripheral Identifier */ +#define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */ +#define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ +#define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */ + +#define AT_XDMAC_CHAN_REG_BASE 0x50 /* Channel registers base address */ + +/* Microblock control members */ +#define AT_XDMAC_MBR_UBC_UBLEN_MAX 0xFFFFFFUL /* Maximum Microblock Length */ +#define AT_XDMAC_MBR_UBC_NDE (0x1 << 24) /* Next Descriptor Enable */ +#define AT_XDMAC_MBR_UBC_NSEN (0x1 << 25) /* Next Descriptor Source Update */ +#define AT_XDMAC_MBR_UBC_NDEN (0x1 << 26) /* Next Descriptor Destination Update */ +#define AT_XDMAC_MBR_UBC_NDV0 (0x0 << 27) /* Next Descriptor View 0 */ +#define AT_XDMAC_MBR_UBC_NDV1 (0x1 << 27) /* Next Descriptor View 1 */ +#define AT_XDMAC_MBR_UBC_NDV2 (0x2 << 27) /* Next Descriptor View 2 */ +#define AT_XDMAC_MBR_UBC_NDV3 (0x3 << 27) /* Next Descriptor View 3 */ + +#define AT_XDMAC_MAX_CHAN 0x20 + +#define AT_XDMAC_DMA_BUSWIDTHS\ + (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |\ + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) + +enum atc_status { + AT_XDMAC_CHAN_IS_CYCLIC = 0, + AT_XDMAC_CHAN_IS_PAUSED, +}; + +/* ----- Channels ----- */ +struct at_xdmac_chan { + struct dma_chan chan; + void __iomem *ch_regs; + u32 mask; /* Channel Mask */ + u32 cfg[2]; /* Channel Configuration Register */ + #define AT_XDMAC_DEV_TO_MEM_CFG 0 /* Predifined dev to mem channel conf */ + #define AT_XDMAC_MEM_TO_DEV_CFG 1 /* Predifined mem to dev channel conf */ + u8 perid; /* Peripheral ID */ + u8 perif; /* Peripheral Interface */ + u8 memif; /* Memory Interface */ + u32 per_src_addr; + u32 per_dst_addr; + u32 save_cc; + u32 save_cim; + u32 save_cnda; + u32 save_cndc; + unsigned long status; + struct tasklet_struct tasklet; + + spinlock_t lock; + + struct list_head xfers_list; + struct list_head free_descs_list; +}; + + +/* ----- Controller ----- */ +struct at_xdmac { + struct dma_device dma; + void __iomem *regs; + int irq; + struct clk *clk; + u32 save_gim; + u32 save_gs; + struct dma_pool *at_xdmac_desc_pool; + struct at_xdmac_chan chan[0]; +}; + + +/* ----- Descriptors ----- */ + +/* Linked List Descriptor */ +struct at_xdmac_lld { + dma_addr_t mbr_nda; /* Next Descriptor Member */ + u32 mbr_ubc; /* Microblock Control Member */ + dma_addr_t mbr_sa; /* Source Address Member */ + dma_addr_t mbr_da; /* Destination Address Member */ + u32 mbr_cfg; /* Configuration Register */ +}; + + +struct at_xdmac_desc { + struct at_xdmac_lld lld; + enum dma_transfer_direction direction; + struct dma_async_tx_descriptor tx_dma_desc; + struct list_head desc_node; + /* Following members are only used by the first descriptor */ + bool active_xfer; + unsigned int xfer_size; + struct list_head descs_list; + struct list_head xfer_node; +}; + +static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb) +{ + return atxdmac->regs + (AT_XDMAC_CHAN_REG_BASE + chan_nb * 0x40); +} + +#define at_xdmac_read(atxdmac, reg) readl_relaxed((atxdmac)->regs + (reg)) +#define at_xdmac_write(atxdmac, reg, value) \ + writel_relaxed((value), (atxdmac)->regs + (reg)) + +#define at_xdmac_chan_read(atchan, reg) readl_relaxed((atchan)->ch_regs + (reg)) +#define at_xdmac_chan_write(atchan, reg, value) writel_relaxed((value), (atchan)->ch_regs + (reg)) + +static inline struct at_xdmac_chan *to_at_xdmac_chan(struct dma_chan *dchan) +{ + return container_of(dchan, struct at_xdmac_chan, chan); +} + +static struct device *chan2dev(struct dma_chan *chan) +{ + return &chan->dev->device; +} + +static inline struct at_xdmac *to_at_xdmac(struct dma_device *ddev) +{ + return container_of(ddev, struct at_xdmac, dma); +} + +static inline struct at_xdmac_desc *txd_to_at_desc(struct dma_async_tx_descriptor *txd) +{ + return container_of(txd, struct at_xdmac_desc, tx_dma_desc); +} + +static inline int at_xdmac_chan_is_cyclic(struct at_xdmac_chan *atchan) +{ + return test_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); +} + +static inline int at_xdmac_chan_is_paused(struct at_xdmac_chan *atchan) +{ + return test_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); +} + +static inline int at_xdmac_csize(u32 maxburst) +{ + int csize; + + csize = ffs(maxburst) - 1; + if (csize > 4) + csize = -EINVAL; + + return csize; +}; + +static inline u8 at_xdmac_get_dwidth(u32 cfg) +{ + return (cfg & AT_XDMAC_CC_DWIDTH_MASK) >> AT_XDMAC_CC_DWIDTH_OFFSET; +}; + +static unsigned int init_nr_desc_per_channel = 64; +module_param(init_nr_desc_per_channel, uint, 0644); +MODULE_PARM_DESC(init_nr_desc_per_channel, + "initial descriptors per channel (default: 64)"); + + +static bool at_xdmac_chan_is_enabled(struct at_xdmac_chan *atchan) +{ + return at_xdmac_chan_read(atchan, AT_XDMAC_GS) & atchan->mask; +} + +static void at_xdmac_off(struct at_xdmac *atxdmac) +{ + at_xdmac_write(atxdmac, AT_XDMAC_GD, -1L); + + /* Wait that all chans are disabled. */ + while (at_xdmac_read(atxdmac, AT_XDMAC_GS)) + cpu_relax(); + + at_xdmac_write(atxdmac, AT_XDMAC_GID, -1L); +} + +/* Call with lock hold. */ +static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, + struct at_xdmac_desc *first) +{ + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + u32 reg; + + dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); + + if (at_xdmac_chan_is_enabled(atchan)) + return; + + /* Set transfer as active to not try to start it again. */ + first->active_xfer = true; + + /* Tell xdmac where to get the first descriptor. */ + reg = AT_XDMAC_CNDA_NDA(first->tx_dma_desc.phys) + | AT_XDMAC_CNDA_NDAIF(atchan->memif); + at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, reg); + + /* + * When doing non cyclic transfer we need to use the next + * descriptor view 2 since some fields of the configuration register + * depend on transfer size and src/dest addresses. + */ + if (at_xdmac_chan_is_cyclic(atchan)) { + reg = AT_XDMAC_CNDC_NDVIEW_NDV1; + at_xdmac_chan_write(atchan, AT_XDMAC_CC, first->lld.mbr_cfg); + } else { + /* + * No need to write AT_XDMAC_CC reg, it will be done when the + * descriptor is fecthed. + */ + reg = AT_XDMAC_CNDC_NDVIEW_NDV2; + } + + reg |= AT_XDMAC_CNDC_NDDUP + | AT_XDMAC_CNDC_NDSUP + | AT_XDMAC_CNDC_NDE; + at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, reg); + + dev_vdbg(chan2dev(&atchan->chan), + "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", + __func__, at_xdmac_chan_read(atchan, AT_XDMAC_CC), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDC), + at_xdmac_chan_read(atchan, AT_XDMAC_CSA), + at_xdmac_chan_read(atchan, AT_XDMAC_CDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CUBC)); + + at_xdmac_chan_write(atchan, AT_XDMAC_CID, 0xffffffff); + reg = AT_XDMAC_CIE_RBEIE | AT_XDMAC_CIE_WBEIE | AT_XDMAC_CIE_ROIE; + /* + * There is no end of list when doing cyclic dma, we need to get + * an interrupt after each periods. + */ + if (at_xdmac_chan_is_cyclic(atchan)) + at_xdmac_chan_write(atchan, AT_XDMAC_CIE, + reg | AT_XDMAC_CIE_BIE); + else + at_xdmac_chan_write(atchan, AT_XDMAC_CIE, + reg | AT_XDMAC_CIE_LIE); + at_xdmac_write(atxdmac, AT_XDMAC_GIE, atchan->mask); + dev_vdbg(chan2dev(&atchan->chan), + "%s: enable channel (0x%08x)\n", __func__, atchan->mask); + wmb(); + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); + + dev_vdbg(chan2dev(&atchan->chan), + "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", + __func__, at_xdmac_chan_read(atchan, AT_XDMAC_CC), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDC), + at_xdmac_chan_read(atchan, AT_XDMAC_CSA), + at_xdmac_chan_read(atchan, AT_XDMAC_CDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CUBC)); + +} + +static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct at_xdmac_desc *desc = txd_to_at_desc(tx); + struct at_xdmac_chan *atchan = to_at_xdmac_chan(tx->chan); + dma_cookie_t cookie; + + spin_lock_bh(&atchan->lock); + cookie = dma_cookie_assign(tx); + + dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", + __func__, atchan, desc); + list_add_tail(&desc->xfer_node, &atchan->xfers_list); + if (list_is_singular(&atchan->xfers_list)) + at_xdmac_start_xfer(atchan, desc); + + spin_unlock_bh(&atchan->lock); + return cookie; +} + +static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan, + gfp_t gfp_flags) +{ + struct at_xdmac_desc *desc; + struct at_xdmac *atxdmac = to_at_xdmac(chan->device); + dma_addr_t phys; + + desc = dma_pool_alloc(atxdmac->at_xdmac_desc_pool, gfp_flags, &phys); + if (desc) { + memset(desc, 0, sizeof(*desc)); + INIT_LIST_HEAD(&desc->descs_list); + dma_async_tx_descriptor_init(&desc->tx_dma_desc, chan); + desc->tx_dma_desc.tx_submit = at_xdmac_tx_submit; + desc->tx_dma_desc.phys = phys; + } + + return desc; +} + +/* Call must be protected by lock. */ +static struct at_xdmac_desc *at_xdmac_get_desc(struct at_xdmac_chan *atchan) +{ + struct at_xdmac_desc *desc; + + if (list_empty(&atchan->free_descs_list)) { + desc = at_xdmac_alloc_desc(&atchan->chan, GFP_NOWAIT); + } else { + desc = list_first_entry(&atchan->free_descs_list, + struct at_xdmac_desc, desc_node); + list_del(&desc->desc_node); + desc->active_xfer = false; + } + + return desc; +} + +static struct dma_chan *at_xdmac_xlate(struct of_phandle_args *dma_spec, + struct of_dma *of_dma) +{ + struct at_xdmac *atxdmac = of_dma->of_dma_data; + struct at_xdmac_chan *atchan; + struct dma_chan *chan; + struct device *dev = atxdmac->dma.dev; + + if (dma_spec->args_count != 1) { + dev_err(dev, "dma phandler args: bad number of args\n"); + return NULL; + } + + chan = dma_get_any_slave_channel(&atxdmac->dma); + if (!chan) { + dev_err(dev, "can't get a dma channel\n"); + return NULL; + } + + atchan = to_at_xdmac_chan(chan); + atchan->memif = AT91_XDMAC_DT_GET_MEM_IF(dma_spec->args[0]); + atchan->perif = AT91_XDMAC_DT_GET_PER_IF(dma_spec->args[0]); + atchan->perid = AT91_XDMAC_DT_GET_PERID(dma_spec->args[0]); + dev_dbg(dev, "chan dt cfg: memif=%u perif=%u perid=%u\n", + atchan->memif, atchan->perif, atchan->perid); + + return chan; +} + +static int at_xdmac_set_slave_config(struct dma_chan *chan, + struct dma_slave_config *sconfig) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + u8 dwidth; + int csize; + + atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] = + AT91_XDMAC_DT_PERID(atchan->perid) + | AT_XDMAC_CC_DAM_INCREMENTED_AM + | AT_XDMAC_CC_SAM_FIXED_AM + | AT_XDMAC_CC_DIF(atchan->memif) + | AT_XDMAC_CC_SIF(atchan->perif) + | AT_XDMAC_CC_SWREQ_HWR_CONNECTED + | AT_XDMAC_CC_DSYNC_PER2MEM + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_PER_TRAN; + csize = at_xdmac_csize(sconfig->src_maxburst); + if (csize < 0) { + dev_err(chan2dev(chan), "invalid src maxburst value\n"); + return -EINVAL; + } + atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] |= AT_XDMAC_CC_CSIZE(csize); + dwidth = ffs(sconfig->src_addr_width) - 1; + atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] |= AT_XDMAC_CC_DWIDTH(dwidth); + + + atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] = + AT91_XDMAC_DT_PERID(atchan->perid) + | AT_XDMAC_CC_DAM_FIXED_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM + | AT_XDMAC_CC_DIF(atchan->perif) + | AT_XDMAC_CC_SIF(atchan->memif) + | AT_XDMAC_CC_SWREQ_HWR_CONNECTED + | AT_XDMAC_CC_DSYNC_MEM2PER + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_PER_TRAN; + csize = at_xdmac_csize(sconfig->dst_maxburst); + if (csize < 0) { + dev_err(chan2dev(chan), "invalid src maxburst value\n"); + return -EINVAL; + } + atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] |= AT_XDMAC_CC_CSIZE(csize); + dwidth = ffs(sconfig->dst_addr_width) - 1; + atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] |= AT_XDMAC_CC_DWIDTH(dwidth); + + /* Src and dst addr are needed to configure the link list descriptor. */ + atchan->per_src_addr = sconfig->src_addr; + atchan->per_dst_addr = sconfig->dst_addr; + + dev_dbg(chan2dev(chan), + "%s: cfg[dev2mem]=0x%08x, cfg[mem2dev]=0x%08x, per_src_addr=0x%08x, per_dst_addr=0x%08x\n", + __func__, atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG], + atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG], + atchan->per_src_addr, atchan->per_dst_addr); + + return 0; +} + +static struct dma_async_tx_descriptor * +at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction direction, + unsigned long flags, void *context) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac_desc *first = NULL, *prev = NULL; + struct scatterlist *sg; + int i; + unsigned int xfer_size = 0; + + if (!sgl) + return NULL; + + if (!is_slave_direction(direction)) { + dev_err(chan2dev(chan), "invalid DMA direction\n"); + return NULL; + } + + dev_dbg(chan2dev(chan), "%s: sg_len=%d, dir=%s, flags=0x%lx\n", + __func__, sg_len, + direction == DMA_MEM_TO_DEV ? "to device" : "from device", + flags); + + /* Protect dma_sconfig field that can be modified by set_slave_conf. */ + spin_lock_bh(&atchan->lock); + + /* Prepare descriptors. */ + for_each_sg(sgl, sg, sg_len, i) { + struct at_xdmac_desc *desc = NULL; + u32 len, mem, dwidth, fixed_dwidth; + + len = sg_dma_len(sg); + mem = sg_dma_address(sg); + if (unlikely(!len)) { + dev_err(chan2dev(chan), "sg data length is zero\n"); + spin_unlock_bh(&atchan->lock); + return NULL; + } + dev_dbg(chan2dev(chan), "%s: * sg%d len=%u, mem=0x%08x\n", + __func__, i, len, mem); + + desc = at_xdmac_get_desc(atchan); + if (!desc) { + dev_err(chan2dev(chan), "can't get descriptor\n"); + if (first) + list_splice_init(&first->descs_list, &atchan->free_descs_list); + spin_unlock_bh(&atchan->lock); + return NULL; + } + + /* Linked list descriptor setup. */ + if (direction == DMA_DEV_TO_MEM) { + desc->lld.mbr_sa = atchan->per_src_addr; + desc->lld.mbr_da = mem; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; + } else { + desc->lld.mbr_sa = mem; + desc->lld.mbr_da = atchan->per_dst_addr; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; + } + dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); + fixed_dwidth = IS_ALIGNED(len, 1 << dwidth) + ? at_xdmac_get_dwidth(desc->lld.mbr_cfg) + : AT_XDMAC_CC_DWIDTH_BYTE; + desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV2 /* next descriptor view */ + | AT_XDMAC_MBR_UBC_NDEN /* next descriptor dst parameter update */ + | AT_XDMAC_MBR_UBC_NSEN /* next descriptor src parameter update */ + | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */ + | (len >> fixed_dwidth); /* microblock length */ + dev_dbg(chan2dev(chan), + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); + + /* Chain lld. */ + if (prev) { + prev->lld.mbr_nda = desc->tx_dma_desc.phys; + dev_dbg(chan2dev(chan), + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); + } + + prev = desc; + if (!first) + first = desc; + + dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + __func__, desc, first); + list_add_tail(&desc->desc_node, &first->descs_list); + xfer_size += len; + } + + spin_unlock_bh(&atchan->lock); + + first->tx_dma_desc.flags = flags; + first->xfer_size = xfer_size; + first->direction = direction; + + return &first->tx_dma_desc; +} + +static struct dma_async_tx_descriptor * +at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, + size_t buf_len, size_t period_len, + enum dma_transfer_direction direction, + unsigned long flags) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac_desc *first = NULL, *prev = NULL; + unsigned int periods = buf_len / period_len; + int i; + u32 cfg; + + dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", + __func__, &buf_addr, buf_len, period_len, + direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags); + + if (!is_slave_direction(direction)) { + dev_err(chan2dev(chan), "invalid DMA direction\n"); + return NULL; + } + + if (test_and_set_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status)) { + dev_err(chan2dev(chan), "channel currently used\n"); + return NULL; + } + + for (i = 0; i < periods; i++) { + struct at_xdmac_desc *desc = NULL; + + spin_lock_bh(&atchan->lock); + desc = at_xdmac_get_desc(atchan); + if (!desc) { + dev_err(chan2dev(chan), "can't get descriptor\n"); + if (first) + list_splice_init(&first->descs_list, &atchan->free_descs_list); + spin_unlock_bh(&atchan->lock); + return NULL; + } + spin_unlock_bh(&atchan->lock); + dev_dbg(chan2dev(chan), + "%s: desc=0x%p, tx_dma_desc.phys=%pad\n", + __func__, desc, &desc->tx_dma_desc.phys); + + if (direction == DMA_DEV_TO_MEM) { + desc->lld.mbr_sa = atchan->per_src_addr; + desc->lld.mbr_da = buf_addr + i * period_len; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; + } else { + desc->lld.mbr_sa = buf_addr + i * period_len; + desc->lld.mbr_da = atchan->per_dst_addr; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; + } + desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 + | AT_XDMAC_MBR_UBC_NDEN + | AT_XDMAC_MBR_UBC_NSEN + | AT_XDMAC_MBR_UBC_NDE + | period_len >> at_xdmac_get_dwidth(desc->lld.mbr_cfg); + + dev_dbg(chan2dev(chan), + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); + + /* Chain lld. */ + if (prev) { + prev->lld.mbr_nda = desc->tx_dma_desc.phys; + dev_dbg(chan2dev(chan), + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); + } + + prev = desc; + if (!first) + first = desc; + + dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + __func__, desc, first); + list_add_tail(&desc->desc_node, &first->descs_list); + } + + prev->lld.mbr_nda = first->tx_dma_desc.phys; + dev_dbg(chan2dev(chan), + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); + first->tx_dma_desc.flags = flags; + first->xfer_size = buf_len; + first->direction = direction; + + return &first->tx_dma_desc; +} + +static struct dma_async_tx_descriptor * +at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + size_t len, unsigned long flags) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac_desc *first = NULL, *prev = NULL; + size_t remaining_size = len, xfer_size = 0, ublen; + dma_addr_t src_addr = src, dst_addr = dest; + u32 dwidth; + /* + * WARNING: We don't know the direction, it involves we can't + * dynamically set the source and dest interface so we have to use the + * same one. Only interface 0 allows EBI access. Hopefully we can + * access DDR through both ports (at least on SAMA5D4x), so we can use + * the same interface for source and dest, that solves the fact we + * don't know the direction. + */ + u32 chan_cc = AT_XDMAC_CC_DAM_INCREMENTED_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM + | AT_XDMAC_CC_DIF(0) + | AT_XDMAC_CC_SIF(0) + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_MEM_TRAN; + + dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", + __func__, &src, &dest, len, flags); + + if (unlikely(!len)) + return NULL; + + /* + * Check address alignment to select the greater data width we can use. + * Some XDMAC implementations don't provide dword transfer, in this + * case selecting dword has the same behavior as selecting word transfers. + */ + if (!((src_addr | dst_addr) & 7)) { + dwidth = AT_XDMAC_CC_DWIDTH_DWORD; + dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__); + } else if (!((src_addr | dst_addr) & 3)) { + dwidth = AT_XDMAC_CC_DWIDTH_WORD; + dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__); + } else if (!((src_addr | dst_addr) & 1)) { + dwidth = AT_XDMAC_CC_DWIDTH_HALFWORD; + dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__); + } else { + dwidth = AT_XDMAC_CC_DWIDTH_BYTE; + dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__); + } + + /* Prepare descriptors. */ + while (remaining_size) { + struct at_xdmac_desc *desc = NULL; + + dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); + + spin_lock_bh(&atchan->lock); + desc = at_xdmac_get_desc(atchan); + spin_unlock_bh(&atchan->lock); + if (!desc) { + dev_err(chan2dev(chan), "can't get descriptor\n"); + if (first) + list_splice_init(&first->descs_list, &atchan->free_descs_list); + return NULL; + } + + /* Update src and dest addresses. */ + src_addr += xfer_size; + dst_addr += xfer_size; + + if (remaining_size >= AT_XDMAC_MBR_UBC_UBLEN_MAX << dwidth) + xfer_size = AT_XDMAC_MBR_UBC_UBLEN_MAX << dwidth; + else + xfer_size = remaining_size; + + dev_dbg(chan2dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size); + + /* Check remaining length and change data width if needed. */ + if (!((src_addr | dst_addr | xfer_size) & 7)) { + dwidth = AT_XDMAC_CC_DWIDTH_DWORD; + dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__); + } else if (!((src_addr | dst_addr | xfer_size) & 3)) { + dwidth = AT_XDMAC_CC_DWIDTH_WORD; + dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__); + } else if (!((src_addr | dst_addr | xfer_size) & 1)) { + dwidth = AT_XDMAC_CC_DWIDTH_HALFWORD; + dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__); + } else if ((src_addr | dst_addr | xfer_size) & 1) { + dwidth = AT_XDMAC_CC_DWIDTH_BYTE; + dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__); + } + chan_cc |= AT_XDMAC_CC_DWIDTH(dwidth); + + ublen = xfer_size >> dwidth; + remaining_size -= xfer_size; + + desc->lld.mbr_sa = src_addr; + desc->lld.mbr_da = dst_addr; + desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV2 + | AT_XDMAC_MBR_UBC_NDEN + | AT_XDMAC_MBR_UBC_NSEN + | (remaining_size ? AT_XDMAC_MBR_UBC_NDE : 0) + | ublen; + desc->lld.mbr_cfg = chan_cc; + + dev_dbg(chan2dev(chan), + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); + + /* Chain lld. */ + if (prev) { + prev->lld.mbr_nda = desc->tx_dma_desc.phys; + dev_dbg(chan2dev(chan), + "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", + __func__, prev, prev->lld.mbr_nda); + } + + prev = desc; + if (!first) + first = desc; + + dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + __func__, desc, first); + list_add_tail(&desc->desc_node, &first->descs_list); + } + + first->tx_dma_desc.flags = flags; + first->xfer_size = len; + + return &first->tx_dma_desc; +} + +static enum dma_status +at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + struct at_xdmac_desc *desc, *_desc; + struct list_head *descs_list; + enum dma_status ret; + int residue; + u32 cur_nda, mask, value; + u8 dwidth = 0; + + ret = dma_cookie_status(chan, cookie, txstate); + if (ret == DMA_COMPLETE) + return ret; + + if (!txstate) + return ret; + + spin_lock_bh(&atchan->lock); + + desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); + + /* + * If the transfer has not been started yet, don't need to compute the + * residue, it's the transfer length. + */ + if (!desc->active_xfer) { + dma_set_residue(txstate, desc->xfer_size); + spin_unlock_bh(&atchan->lock); + return ret; + } + + residue = desc->xfer_size; + /* + * Flush FIFO: only relevant when the transfer is source peripheral + * synchronized. + */ + mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC; + value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM; + if ((desc->lld.mbr_cfg & mask) == value) { + at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); + while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) + cpu_relax(); + } + + cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; + /* + * Remove size of all microblocks already transferred and the current + * one. Then add the remaining size to transfer of the current + * microblock. + */ + descs_list = &desc->descs_list; + list_for_each_entry_safe(desc, _desc, descs_list, desc_node) { + dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); + residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth; + if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda) + break; + } + residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth; + + spin_unlock_bh(&atchan->lock); + + dma_set_residue(txstate, residue); + + dev_dbg(chan2dev(chan), + "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n", + __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); + + return ret; +} + +/* Call must be protected by lock. */ +static void at_xdmac_remove_xfer(struct at_xdmac_chan *atchan, + struct at_xdmac_desc *desc) +{ + dev_dbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); + + /* + * Remove the transfer from the transfer list then move the transfer + * descriptors into the free descriptors list. + */ + list_del(&desc->xfer_node); + list_splice_init(&desc->descs_list, &atchan->free_descs_list); +} + +static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) +{ + struct at_xdmac_desc *desc; + + spin_lock_bh(&atchan->lock); + + /* + * If channel is enabled, do nothing, advance_work will be triggered + * after the interruption. + */ + if (!at_xdmac_chan_is_enabled(atchan) && !list_empty(&atchan->xfers_list)) { + desc = list_first_entry(&atchan->xfers_list, + struct at_xdmac_desc, + xfer_node); + dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); + if (!desc->active_xfer) + at_xdmac_start_xfer(atchan, desc); + } + + spin_unlock_bh(&atchan->lock); +} + +static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) +{ + struct at_xdmac_desc *desc; + struct dma_async_tx_descriptor *txd; + + desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); + txd = &desc->tx_dma_desc; + + if (txd->callback && (txd->flags & DMA_PREP_INTERRUPT)) + txd->callback(txd->callback_param); +} + +static void at_xdmac_tasklet(unsigned long data) +{ + struct at_xdmac_chan *atchan = (struct at_xdmac_chan *)data; + struct at_xdmac_desc *desc; + u32 error_mask; + + dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08lx\n", + __func__, atchan->status); + + error_mask = AT_XDMAC_CIS_RBEIS + | AT_XDMAC_CIS_WBEIS + | AT_XDMAC_CIS_ROIS; + + if (at_xdmac_chan_is_cyclic(atchan)) { + at_xdmac_handle_cyclic(atchan); + } else if ((atchan->status & AT_XDMAC_CIS_LIS) + || (atchan->status & error_mask)) { + struct dma_async_tx_descriptor *txd; + + if (atchan->status & AT_XDMAC_CIS_RBEIS) + dev_err(chan2dev(&atchan->chan), "read bus error!!!"); + if (atchan->status & AT_XDMAC_CIS_WBEIS) + dev_err(chan2dev(&atchan->chan), "write bus error!!!"); + if (atchan->status & AT_XDMAC_CIS_ROIS) + dev_err(chan2dev(&atchan->chan), "request overflow error!!!"); + + spin_lock_bh(&atchan->lock); + desc = list_first_entry(&atchan->xfers_list, + struct at_xdmac_desc, + xfer_node); + dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); + BUG_ON(!desc->active_xfer); + + txd = &desc->tx_dma_desc; + + at_xdmac_remove_xfer(atchan, desc); + spin_unlock_bh(&atchan->lock); + + if (!at_xdmac_chan_is_cyclic(atchan)) { + dma_cookie_complete(txd); + if (txd->callback && (txd->flags & DMA_PREP_INTERRUPT)) + txd->callback(txd->callback_param); + } + + dma_run_dependencies(txd); + + at_xdmac_advance_work(atchan); + } +} + +static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) +{ + struct at_xdmac *atxdmac = (struct at_xdmac *)dev_id; + struct at_xdmac_chan *atchan; + u32 imr, status, pending; + u32 chan_imr, chan_status; + int i, ret = IRQ_NONE; + + do { + imr = at_xdmac_read(atxdmac, AT_XDMAC_GIM); + status = at_xdmac_read(atxdmac, AT_XDMAC_GIS); + pending = status & imr; + + dev_vdbg(atxdmac->dma.dev, + "%s: status=0x%08x, imr=0x%08x, pending=0x%08x\n", + __func__, status, imr, pending); + + if (!pending) + break; + + /* We have to find which channel has generated the interrupt. */ + for (i = 0; i < atxdmac->dma.chancnt; i++) { + if (!((1 << i) & pending)) + continue; + + atchan = &atxdmac->chan[i]; + chan_imr = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); + chan_status = at_xdmac_chan_read(atchan, AT_XDMAC_CIS); + atchan->status = chan_status & chan_imr; + dev_vdbg(atxdmac->dma.dev, + "%s: chan%d: imr=0x%x, status=0x%x\n", + __func__, i, chan_imr, chan_status); + dev_vdbg(chan2dev(&atchan->chan), + "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", + __func__, + at_xdmac_chan_read(atchan, AT_XDMAC_CC), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CNDC), + at_xdmac_chan_read(atchan, AT_XDMAC_CSA), + at_xdmac_chan_read(atchan, AT_XDMAC_CDA), + at_xdmac_chan_read(atchan, AT_XDMAC_CUBC)); + + if (atchan->status & (AT_XDMAC_CIS_RBEIS | AT_XDMAC_CIS_WBEIS)) + at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); + + tasklet_schedule(&atchan->tasklet); + ret = IRQ_HANDLED; + } + + } while (pending); + + return ret; +} + +static void at_xdmac_issue_pending(struct dma_chan *chan) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + + dev_dbg(chan2dev(&atchan->chan), "%s\n", __func__); + + if (!at_xdmac_chan_is_cyclic(atchan)) + at_xdmac_advance_work(atchan); + + return; +} + +static int at_xdmac_device_config(struct dma_chan *chan, + struct dma_slave_config *config) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + int ret; + + dev_dbg(chan2dev(chan), "%s\n", __func__); + + spin_lock_bh(&atchan->lock); + ret = at_xdmac_set_slave_config(chan, config); + spin_unlock_bh(&atchan->lock); + + return ret; +} + +static int at_xdmac_device_pause(struct dma_chan *chan) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + + dev_dbg(chan2dev(chan), "%s\n", __func__); + + if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status)) + return 0; + + spin_lock_bh(&atchan->lock); + at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask); + while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) + & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) + cpu_relax(); + spin_unlock_bh(&atchan->lock); + + return 0; +} + +static int at_xdmac_device_resume(struct dma_chan *chan) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + + dev_dbg(chan2dev(chan), "%s\n", __func__); + + spin_lock_bh(&atchan->lock); + if (!at_xdmac_chan_is_paused(atchan)) + return 0; + + at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask); + clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); + spin_unlock_bh(&atchan->lock); + + return 0; +} + +static int at_xdmac_device_terminate_all(struct dma_chan *chan) +{ + struct at_xdmac_desc *desc, *_desc; + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + + dev_dbg(chan2dev(chan), "%s\n", __func__); + + spin_lock_bh(&atchan->lock); + at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); + while (at_xdmac_read(atxdmac, AT_XDMAC_GS) & atchan->mask) + cpu_relax(); + + /* Cancel all pending transfers. */ + list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node) + at_xdmac_remove_xfer(atchan, desc); + + clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); + spin_unlock_bh(&atchan->lock); + + return 0; +} + +static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac_desc *desc; + int i; + + spin_lock_bh(&atchan->lock); + + if (at_xdmac_chan_is_enabled(atchan)) { + dev_err(chan2dev(chan), + "can't allocate channel resources (channel enabled)\n"); + i = -EIO; + goto spin_unlock; + } + + if (!list_empty(&atchan->free_descs_list)) { + dev_err(chan2dev(chan), + "can't allocate channel resources (channel not free from a previous use)\n"); + i = -EIO; + goto spin_unlock; + } + + for (i = 0; i < init_nr_desc_per_channel; i++) { + desc = at_xdmac_alloc_desc(chan, GFP_ATOMIC); + if (!desc) { + dev_warn(chan2dev(chan), + "only %d descriptors have been allocated\n", i); + break; + } + list_add_tail(&desc->desc_node, &atchan->free_descs_list); + } + + dma_cookie_init(chan); + + dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i); + +spin_unlock: + spin_unlock_bh(&atchan->lock); + return i; +} + +static void at_xdmac_free_chan_resources(struct dma_chan *chan) +{ + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + struct at_xdmac *atxdmac = to_at_xdmac(chan->device); + struct at_xdmac_desc *desc, *_desc; + + list_for_each_entry_safe(desc, _desc, &atchan->free_descs_list, desc_node) { + dev_dbg(chan2dev(chan), "%s: freeing descriptor %p\n", __func__, desc); + list_del(&desc->desc_node); + dma_pool_free(atxdmac->at_xdmac_desc_pool, desc, desc->tx_dma_desc.phys); + } + + return; +} + +#ifdef CONFIG_PM +static int atmel_xdmac_prepare(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct at_xdmac *atxdmac = platform_get_drvdata(pdev); + struct dma_chan *chan, *_chan; + + list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + + /* Wait for transfer completion, except in cyclic case. */ + if (at_xdmac_chan_is_enabled(atchan) && !at_xdmac_chan_is_cyclic(atchan)) + return -EAGAIN; + } + return 0; +} +#else +# define atmel_xdmac_prepare NULL +#endif + +#ifdef CONFIG_PM_SLEEP +static int atmel_xdmac_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct at_xdmac *atxdmac = platform_get_drvdata(pdev); + struct dma_chan *chan, *_chan; + + list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + + atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC); + if (at_xdmac_chan_is_cyclic(atchan)) { + if (!at_xdmac_chan_is_paused(atchan)) + at_xdmac_device_pause(chan); + atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); + atchan->save_cnda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA); + atchan->save_cndc = at_xdmac_chan_read(atchan, AT_XDMAC_CNDC); + } + } + atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); + + at_xdmac_off(atxdmac); + clk_disable_unprepare(atxdmac->clk); + return 0; +} + +static int atmel_xdmac_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct at_xdmac *atxdmac = platform_get_drvdata(pdev); + struct at_xdmac_chan *atchan; + struct dma_chan *chan, *_chan; + int i; + + clk_prepare_enable(atxdmac->clk); + + /* Clear pending interrupts. */ + for (i = 0; i < atxdmac->dma.chancnt; i++) { + atchan = &atxdmac->chan[i]; + while (at_xdmac_chan_read(atchan, AT_XDMAC_CIS)) + cpu_relax(); + } + + at_xdmac_write(atxdmac, AT_XDMAC_GIE, atxdmac->save_gim); + at_xdmac_write(atxdmac, AT_XDMAC_GE, atxdmac->save_gs); + list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { + atchan = to_at_xdmac_chan(chan); + at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc); + if (at_xdmac_chan_is_cyclic(atchan)) { + at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda); + at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); + at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); + wmb(); + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); + } + } + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static int at_xdmac_probe(struct platform_device *pdev) +{ + struct resource *res; + struct at_xdmac *atxdmac; + int irq, size, nr_channels, i, ret; + void __iomem *base; + u32 reg; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + /* + * Read number of xdmac channels, read helper function can't be used + * since atxdmac is not yet allocated and we need to know the number + * of channels to do the allocation. + */ + reg = readl_relaxed(base + AT_XDMAC_GTYPE); + nr_channels = AT_XDMAC_NB_CH(reg); + if (nr_channels > AT_XDMAC_MAX_CHAN) { + dev_err(&pdev->dev, "invalid number of channels (%u)\n", + nr_channels); + return -EINVAL; + } + + size = sizeof(*atxdmac); + size += nr_channels * sizeof(struct at_xdmac_chan); + atxdmac = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!atxdmac) { + dev_err(&pdev->dev, "can't allocate at_xdmac structure\n"); + return -ENOMEM; + } + + atxdmac->regs = base; + atxdmac->irq = irq; + + atxdmac->clk = devm_clk_get(&pdev->dev, "dma_clk"); + if (IS_ERR(atxdmac->clk)) { + dev_err(&pdev->dev, "can't get dma_clk\n"); + return PTR_ERR(atxdmac->clk); + } + + /* Do not use dev res to prevent races with tasklet */ + ret = request_irq(atxdmac->irq, at_xdmac_interrupt, 0, "at_xdmac", atxdmac); + if (ret) { + dev_err(&pdev->dev, "can't request irq\n"); + return ret; + } + + ret = clk_prepare_enable(atxdmac->clk); + if (ret) { + dev_err(&pdev->dev, "can't prepare or enable clock\n"); + goto err_free_irq; + } + + atxdmac->at_xdmac_desc_pool = + dmam_pool_create(dev_name(&pdev->dev), &pdev->dev, + sizeof(struct at_xdmac_desc), 4, 0); + if (!atxdmac->at_xdmac_desc_pool) { + dev_err(&pdev->dev, "no memory for descriptors dma pool\n"); + ret = -ENOMEM; + goto err_clk_disable; + } + + dma_cap_set(DMA_CYCLIC, atxdmac->dma.cap_mask); + dma_cap_set(DMA_MEMCPY, atxdmac->dma.cap_mask); + dma_cap_set(DMA_SLAVE, atxdmac->dma.cap_mask); + /* + * Without DMA_PRIVATE the driver is not able to allocate more than + * one channel, second allocation fails in private_candidate. + */ + dma_cap_set(DMA_PRIVATE, atxdmac->dma.cap_mask); + atxdmac->dma.dev = &pdev->dev; + atxdmac->dma.device_alloc_chan_resources = at_xdmac_alloc_chan_resources; + atxdmac->dma.device_free_chan_resources = at_xdmac_free_chan_resources; + atxdmac->dma.device_tx_status = at_xdmac_tx_status; + atxdmac->dma.device_issue_pending = at_xdmac_issue_pending; + atxdmac->dma.device_prep_dma_cyclic = at_xdmac_prep_dma_cyclic; + atxdmac->dma.device_prep_dma_memcpy = at_xdmac_prep_dma_memcpy; + atxdmac->dma.device_prep_slave_sg = at_xdmac_prep_slave_sg; + atxdmac->dma.device_config = at_xdmac_device_config; + atxdmac->dma.device_pause = at_xdmac_device_pause; + atxdmac->dma.device_resume = at_xdmac_device_resume; + atxdmac->dma.device_terminate_all = at_xdmac_device_terminate_all; + atxdmac->dma.src_addr_widths = AT_XDMAC_DMA_BUSWIDTHS; + atxdmac->dma.dst_addr_widths = AT_XDMAC_DMA_BUSWIDTHS; + atxdmac->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + atxdmac->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + + /* Disable all chans and interrupts. */ + at_xdmac_off(atxdmac); + + /* Init channels. */ + INIT_LIST_HEAD(&atxdmac->dma.channels); + for (i = 0; i < nr_channels; i++) { + struct at_xdmac_chan *atchan = &atxdmac->chan[i]; + + atchan->chan.device = &atxdmac->dma; + list_add_tail(&atchan->chan.device_node, + &atxdmac->dma.channels); + + atchan->ch_regs = at_xdmac_chan_reg_base(atxdmac, i); + atchan->mask = 1 << i; + + spin_lock_init(&atchan->lock); + INIT_LIST_HEAD(&atchan->xfers_list); + INIT_LIST_HEAD(&atchan->free_descs_list); + tasklet_init(&atchan->tasklet, at_xdmac_tasklet, + (unsigned long)atchan); + + /* Clear pending interrupts. */ + while (at_xdmac_chan_read(atchan, AT_XDMAC_CIS)) + cpu_relax(); + } + platform_set_drvdata(pdev, atxdmac); + + ret = dma_async_device_register(&atxdmac->dma); + if (ret) { + dev_err(&pdev->dev, "fail to register DMA engine device\n"); + goto err_clk_disable; + } + + ret = of_dma_controller_register(pdev->dev.of_node, + at_xdmac_xlate, atxdmac); + if (ret) { + dev_err(&pdev->dev, "could not register of dma controller\n"); + goto err_dma_unregister; + } + + dev_info(&pdev->dev, "%d channels, mapped at 0x%p\n", + nr_channels, atxdmac->regs); + + return 0; + +err_dma_unregister: + dma_async_device_unregister(&atxdmac->dma); +err_clk_disable: + clk_disable_unprepare(atxdmac->clk); +err_free_irq: + free_irq(atxdmac->irq, atxdmac->dma.dev); + return ret; +} + +static int at_xdmac_remove(struct platform_device *pdev) +{ + struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); + int i; + + at_xdmac_off(atxdmac); + of_dma_controller_free(pdev->dev.of_node); + dma_async_device_unregister(&atxdmac->dma); + clk_disable_unprepare(atxdmac->clk); + + synchronize_irq(atxdmac->irq); + + free_irq(atxdmac->irq, atxdmac->dma.dev); + + for (i = 0; i < atxdmac->dma.chancnt; i++) { + struct at_xdmac_chan *atchan = &atxdmac->chan[i]; + + tasklet_kill(&atchan->tasklet); + at_xdmac_free_chan_resources(&atchan->chan); + } + + return 0; +} + +static const struct dev_pm_ops atmel_xdmac_dev_pm_ops = { + .prepare = atmel_xdmac_prepare, + SET_LATE_SYSTEM_SLEEP_PM_OPS(atmel_xdmac_suspend, atmel_xdmac_resume) +}; + +static const struct of_device_id atmel_xdmac_dt_ids[] = { + { + .compatible = "atmel,sama5d4-dma", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, atmel_xdmac_dt_ids); + +static struct platform_driver at_xdmac_driver = { + .probe = at_xdmac_probe, + .remove = at_xdmac_remove, + .driver = { + .name = "at_xdmac", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(atmel_xdmac_dt_ids), + .pm = &atmel_xdmac_dev_pm_ops, + } +}; + +static int __init at_xdmac_init(void) +{ + return platform_driver_probe(&at_xdmac_driver, at_xdmac_probe); +} +subsys_initcall(at_xdmac_init); + +MODULE_DESCRIPTION("Atmel Extended DMA Controller driver"); +MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@atmel.com>"); +MODULE_LICENSE("GPL"); Index: linux-3.18.13-rt10-r7s4/drivers/dma/bcm2835-dma.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/bcm2835-dma.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/bcm2835-dma.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:574 @ static int bcm2835_dma_device_slave_caps struct dma_slave_caps *caps) { caps->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - caps->dstn_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + caps->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = false; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/dmaengine.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/dmaengine.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/dmaengine.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:225 @ static void balance_ref_count(struct dma */ static int dma_chan_get(struct dma_chan *chan) { - int err = -ENODEV; struct module *owner = dma_chan_to_owner(chan); + int ret; + /* The channel is already in use, update client count */ if (chan->client_count) { __module_get(owner); - err = 0; - } else if (try_module_get(owner)) - err = 0; + goto out; + } - if (err == 0) - chan->client_count++; + if (!try_module_get(owner)) + return -ENODEV; /* allocate upon first client reference */ - if (chan->client_count == 1 && err == 0) { - int desc_cnt = chan->device->device_alloc_chan_resources(chan); - - if (desc_cnt < 0) { - err = desc_cnt; - chan->client_count = 0; - module_put(owner); - } else if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) - balance_ref_count(chan); - } - - return err; + if (chan->device->device_alloc_chan_resources) { + ret = chan->device->device_alloc_chan_resources(chan); + if (ret < 0) + goto err_out; + } + + if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) + balance_ref_count(chan); + +out: + chan->client_count++; + return 0; + +err_out: + module_put(owner); + return ret; } /** @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:264 @ static int dma_chan_get(struct dma_chan */ static void dma_chan_put(struct dma_chan *chan) { + /* This channel is not in use, bail out */ if (!chan->client_count) - return; /* this channel failed alloc_chan_resources */ + return; + chan->client_count--; module_put(dma_chan_to_owner(chan)); - if (chan->client_count == 0) + + /* This channel is not in use anymore, free it */ + if (!chan->client_count && chan->device->device_free_chan_resources) chan->device->device_free_chan_resources(chan); } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:823 @ int dma_async_device_register(struct dma !device->device_prep_dma_sg); BUG_ON(dma_has_cap(DMA_CYCLIC, device->cap_mask) && !device->device_prep_dma_cyclic); - BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && - !device->device_control); BUG_ON(dma_has_cap(DMA_INTERLEAVE, device->cap_mask) && !device->device_prep_interleaved_dma); - BUG_ON(!device->device_alloc_chan_resources); - BUG_ON(!device->device_free_chan_resources); BUG_ON(!device->device_tx_status); BUG_ON(!device->device_issue_pending); BUG_ON(!device->dev); + WARN(dma_has_cap(DMA_SLAVE, device->cap_mask) && !device->directions, + "this driver doesn't support generic slave capabilities reporting\n"); + /* note: this only matters in the * CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=n case */ Index: linux-3.18.13-rt10-r7s4/drivers/dma/edma.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/edma.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/edma.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1001 @ static int edma_dma_device_slave_caps(st struct dma_slave_caps *caps) { caps->src_addr_widths = EDMA_DMA_BUSWIDTHS; - caps->dstn_addr_widths = EDMA_DMA_BUSWIDTHS; + caps->dst_addr_widths = EDMA_DMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = true; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/fsl-edma.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/fsl-edma.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/fsl-edma.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:784 @ static int fsl_dma_device_slave_caps(str struct dma_slave_caps *caps) { caps->src_addr_widths = FSL_EDMA_BUSWIDTHS; - caps->dstn_addr_widths = FSL_EDMA_BUSWIDTHS; + caps->dst_addr_widths = FSL_EDMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = true; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/dma/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:110 @ config AT_HDMAC help Support the Atmel AHB DMA controller. +config AT_XDMAC + tristate "Atmel XDMA support" + depends on ARCH_AT91 + select DMA_ENGINE + help + Support the Atmel XDMA controller. + config FSL_DMA tristate "Freescale Elo series DMA support" depends on FSL_SOC Index: linux-3.18.13-rt10-r7s4/drivers/dma/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/Makefile +++ linux-3.18.13-rt10-r7s4/drivers/dma/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:19 @ obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ obj-$(CONFIG_MV_XOR) += mv_xor.o obj-$(CONFIG_DW_DMAC_CORE) += dw/ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o +obj-$(CONFIG_AT_XDMAC) += at_xdmac.o obj-$(CONFIG_MX3_IPU) += ipu/ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_SH_DMAE_BASE) += sh/ Index: linux-3.18.13-rt10-r7s4/drivers/dma/nbpfaxi.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/nbpfaxi.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/nbpfaxi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1079 @ static int nbpf_slave_caps(struct dma_ch struct dma_slave_caps *caps) { caps->src_addr_widths = NBPF_DMA_BUSWIDTHS; - caps->dstn_addr_widths = NBPF_DMA_BUSWIDTHS; + caps->dst_addr_widths = NBPF_DMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = false; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/omap-dma.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/omap-dma.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/omap-dma.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1103 @ static int omap_dma_device_slave_caps(st struct dma_slave_caps *caps) { caps->src_addr_widths = OMAP_DMA_BUSWIDTHS; - caps->dstn_addr_widths = OMAP_DMA_BUSWIDTHS; + caps->dst_addr_widths = OMAP_DMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = true; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/pl330.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/pl330.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/pl330.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2588 @ static int pl330_dma_device_slave_caps(s struct dma_slave_caps *caps) { caps->src_addr_widths = PL330_DMA_BUSWIDTHS; - caps->dstn_addr_widths = PL330_DMA_BUSWIDTHS; + caps->dst_addr_widths = PL330_DMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = false; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/dma/sirf-dma.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/dma/sirf-dma.c +++ linux-3.18.13-rt10-r7s4/drivers/dma/sirf-dma.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:655 @ static int sirfsoc_dma_device_slave_caps struct dma_slave_caps *caps) { caps->src_addr_widths = SIRFSOC_DMA_BUSWIDTHS; - caps->dstn_addr_widths = SIRFSOC_DMA_BUSWIDTHS; + caps->dst_addr_widths = SIRFSOC_DMA_BUSWIDTHS; caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); caps->cmd_pause = true; caps->cmd_terminate = true; Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-bcm-kona.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-bcm-kona.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-bcm-kona.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:473 @ static int bcm_kona_gpio_irq_reqres(stru { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq)) { + if (gpiochip_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq)) { dev_err(kona_gpio->gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", d->hwirq); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:486 @ static void bcm_kona_gpio_irq_relres(str { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq); + gpiochip_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq); } static struct irq_chip bcm_gpio_irq_chip = { Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-dwapb.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-dwapb.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-dwapb.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:197 @ static int dwapb_irq_reqres(struct irq_d struct dwapb_gpio *gpio = igc->private; struct bgpio_chip *bgc = &gpio->ports[0].bgc; - if (gpio_lock_as_irq(&bgc->gc, irqd_to_hwirq(d))) { + if (gpiochip_lock_as_irq(&bgc->gc, irqd_to_hwirq(d))) { dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:211 @ static void dwapb_irq_relres(struct irq_ struct dwapb_gpio *gpio = igc->private; struct bgpio_chip *bgc = &gpio->ports[0].bgc; - gpio_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d)); + gpiochip_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d)); } static int dwapb_irq_set_type(struct irq_data *d, u32 type) Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-em.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-em.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-em.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:106 @ static int em_gio_irq_reqres(struct irq_ { struct em_gio_priv *p = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d))) { + if (gpiochip_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d))) { dev_err(p->gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:119 @ static void em_gio_irq_relres(struct irq { struct em_gio_priv *p = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d)); + gpiochip_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d)); } Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib-acpi.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpiolib-acpi.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib-acpi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:156 @ static acpi_status acpi_gpiochip_request gpiod_direction_input(desc); - ret = gpio_lock_as_irq(chip, pin); + ret = gpiochip_lock_as_irq(chip, pin); if (ret) { dev_err(chip->dev, "Failed to lock GPIO as interrupt\n"); goto fail_free_desc; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:212 @ static acpi_status acpi_gpiochip_request fail_free_event: kfree(event); fail_unlock_irq: - gpio_unlock_as_irq(chip, pin); + gpiochip_unlock_as_irq(chip, pin); fail_free_desc: gpiochip_free_own_desc(desc); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:283 @ void acpi_gpiochip_free_interrupts(struc desc = event->desc; if (WARN_ON(IS_ERR(desc))) continue; - gpio_unlock_as_irq(chip, event->pin); + gpiochip_unlock_as_irq(chip, event->pin); gpiochip_free_own_desc(desc); list_del(&event->node); kfree(event); Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpiolib.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:498 @ static int gpiochip_irq_reqres(struct ir { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(chip, d->hwirq)) { + if (gpiochip_lock_as_irq(chip, d->hwirq)) { chip_err(chip, "unable to lock HW IRQ %lu for IRQ\n", d->hwirq); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:511 @ static void gpiochip_irq_relres(struct i { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(chip, d->hwirq); + gpiochip_unlock_as_irq(chip, d->hwirq); } static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1335 @ int gpiod_to_irq(const struct gpio_desc EXPORT_SYMBOL_GPL(gpiod_to_irq); /** - * gpio_lock_as_irq() - lock a GPIO to be used as IRQ + * gpiochip_lock_as_irq() - lock a GPIO to be used as IRQ * @chip: the chip the GPIO to lock belongs to * @offset: the offset of the GPIO to lock as IRQ * * This is used directly by GPIO drivers that want to lock down * a certain GPIO line to be used for IRQs. */ -int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) +int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1357 @ int gpio_lock_as_irq(struct gpio_chip *c set_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); return 0; } -EXPORT_SYMBOL_GPL(gpio_lock_as_irq); +EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq); /** - * gpio_unlock_as_irq() - unlock a GPIO used as IRQ + * gpiochip_unlock_as_irq() - unlock a GPIO used as IRQ * @chip: the chip the GPIO to lock belongs to * @offset: the offset of the GPIO to lock as IRQ * * This is used directly by GPIO drivers that want to indicate * that a certain GPIO is no longer used exclusively for IRQ. */ -void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) +void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) return; clear_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); } -EXPORT_SYMBOL_GPL(gpio_unlock_as_irq); +EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); /** * gpiod_get_raw_value_cansleep() - return a gpio's raw value Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib-sysfs.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpiolib-sysfs.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpiolib-sysfs.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:164 @ static int gpio_setup_irq(struct gpio_de desc->flags &= ~GPIO_TRIGGER_MASK; if (!gpio_flags) { - gpio_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); + gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); ret = 0; goto free_id; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:203 @ static int gpio_setup_irq(struct gpio_de if (ret < 0) goto free_id; - ret = gpio_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); + ret = gpiochip_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); if (ret < 0) { gpiod_warn(desc, "failed to flag the GPIO for IRQ\n"); goto free_id; Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-mcp23s08.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-mcp23s08.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-mcp23s08.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:447 @ static int mcp23s08_irq_reqres(struct ir { struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); - if (gpio_lock_as_irq(&mcp->chip, data->hwirq)) { + if (gpiochip_lock_as_irq(&mcp->chip, data->hwirq)) { dev_err(mcp->chip.dev, "unable to lock HW IRQ %lu for IRQ usage\n", data->hwirq); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:461 @ static void mcp23s08_irq_relres(struct i { struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); - gpio_unlock_as_irq(&mcp->chip, data->hwirq); + gpiochip_unlock_as_irq(&mcp->chip, data->hwirq); } static struct irq_chip mcp23s08_irq_chip = { Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-omap.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-omap.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-omap.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:803 @ static void omap_gpio_irq_shutdown(struc unsigned offset = GPIO_INDEX(bank, gpio); spin_lock_irqsave(&bank->lock, flags); - gpio_unlock_as_irq(&bank->chip, offset); + gpiochip_unlock_as_irq(&bank->chip, offset); bank->irq_usage &= ~(BIT(offset)); omap_disable_gpio_module(bank, offset); omap_reset_gpio(bank, gpio); Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-tegra.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-tegra.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-tegra.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:236 @ static int tegra_gpio_irq_set_type(struc return -EINVAL; } - ret = gpio_lock_as_irq(&tegra_gpio_chip, gpio); + ret = gpiochip_lock_as_irq(&tegra_gpio_chip, gpio); if (ret) { dev_err(dev, "unable to lock Tegra GPIO %d as IRQ\n", gpio); return ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:266 @ static void tegra_gpio_irq_shutdown(stru { int gpio = d->hwirq; - gpio_unlock_as_irq(&tegra_gpio_chip, gpio); + gpiochip_unlock_as_irq(&tegra_gpio_chip, gpio); } static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) Index: linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-vr41xx.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpio/gpio-vr41xx.c +++ linux-3.18.13-rt10-r7s4/drivers/gpio/gpio-vr41xx.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:141 @ static void unmask_giuint_low(struct irq static unsigned int startup_giuint(struct irq_data *data) { - if (gpio_lock_as_irq(&vr41xx_gpio_chip, data->hwirq)) + if (gpiochip_lock_as_irq(&vr41xx_gpio_chip, data->hwirq)) dev_err(vr41xx_gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", data->hwirq); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:153 @ static unsigned int startup_giuint(struc static void shutdown_giuint(struct irq_data *data) { mask_giuint_low(data); - gpio_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq); + gpiochip_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq); } static struct irq_chip giuint_low_irq_chip = { Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Traphandler + * Copyright (C) 2014 Free Electrons + * + * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com> + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/pinctrl/consumer.h> + +#include <drm/drm_crtc.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drmP.h> + +#include <video/videomode.h> + +#include "atmel_hlcdc_dc.h" + +/** + * Atmel HLCDC CRTC structure + * + * @base: base DRM CRTC structure + * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device + * @event: pointer to the current page flip event + * @id: CRTC id (returned by drm_crtc_index) + * @dpms: DPMS mode + */ +struct atmel_hlcdc_crtc { + struct drm_crtc base; + struct atmel_hlcdc_dc *dc; + struct drm_pending_vblank_event *event; + int id; + int dpms; +}; + +static inline struct atmel_hlcdc_crtc * +drm_crtc_to_atmel_hlcdc_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct atmel_hlcdc_crtc, base); +} + +static void atmel_hlcdc_crtc_dpms(struct drm_crtc *c, int mode) +{ + struct drm_device *dev = c->dev; + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + struct regmap *regmap = crtc->dc->hlcdc->regmap; + unsigned int status; + + if (mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; + + if (crtc->dpms == mode) + return; + + pm_runtime_get_sync(dev->dev); + + if (mode != DRM_MODE_DPMS_ON) { + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + (status & ATMEL_HLCDC_DISP)) + cpu_relax(); + + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + (status & ATMEL_HLCDC_SYNC)) + cpu_relax(); + + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + (status & ATMEL_HLCDC_PIXEL_CLK)) + cpu_relax(); + + clk_disable_unprepare(crtc->dc->hlcdc->sys_clk); + pinctrl_pm_select_sleep_state(dev->dev); + + pm_runtime_allow(dev->dev); + } else { + pm_runtime_forbid(dev->dev); + + pinctrl_pm_select_default_state(dev->dev); + clk_prepare_enable(crtc->dc->hlcdc->sys_clk); + + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + !(status & ATMEL_HLCDC_PIXEL_CLK)) + cpu_relax(); + + + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + !(status & ATMEL_HLCDC_SYNC)) + cpu_relax(); + + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP); + while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && + !(status & ATMEL_HLCDC_DISP)) + cpu_relax(); + } + + pm_runtime_put_sync(dev->dev); + + crtc->dpms = mode; +} + +static int atmel_hlcdc_crtc_mode_set(struct drm_crtc *c, + struct drm_display_mode *mode, + struct drm_display_mode *adj, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + struct regmap *regmap = crtc->dc->hlcdc->regmap; + struct drm_plane *plane = c->primary; + struct drm_framebuffer *fb; + unsigned long mode_rate; + struct videomode vm; + unsigned long prate; + unsigned int cfg; + int div; + + if (atmel_hlcdc_dc_mode_valid(crtc->dc, adj) != MODE_OK) + return -EINVAL; + + vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay; + vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end; + vm.vsync_len = adj->crtc_vsync_end - adj->crtc_vsync_start; + vm.hfront_porch = adj->crtc_hsync_start - adj->crtc_hdisplay; + vm.hback_porch = adj->crtc_htotal - adj->crtc_hsync_end; + vm.hsync_len = adj->crtc_hsync_end - adj->crtc_hsync_start; + + regmap_write(regmap, ATMEL_HLCDC_CFG(1), + (vm.hsync_len - 1) | ((vm.vsync_len - 1) << 16)); + + regmap_write(regmap, ATMEL_HLCDC_CFG(2), + (vm.vfront_porch - 1) | (vm.vback_porch << 16)); + + regmap_write(regmap, ATMEL_HLCDC_CFG(3), + (vm.hfront_porch - 1) | ((vm.hback_porch - 1) << 16)); + + regmap_write(regmap, ATMEL_HLCDC_CFG(4), + (adj->crtc_hdisplay - 1) | + ((adj->crtc_vdisplay - 1) << 16)); + + cfg = 0; + + prate = clk_get_rate(crtc->dc->hlcdc->sys_clk); + mode_rate = mode->crtc_clock * 1000; + if ((prate / 2) < mode_rate) { + prate *= 2; + cfg |= ATMEL_HLCDC_CLKSEL; + } + + div = DIV_ROUND_UP(prate, mode_rate); + if (div < 2) + div = 2; + + cfg |= ATMEL_HLCDC_CLKDIV(div); + + regmap_update_bits(regmap, ATMEL_HLCDC_CFG(0), + ATMEL_HLCDC_CLKSEL | ATMEL_HLCDC_CLKDIV_MASK | + ATMEL_HLCDC_CLKPOL, cfg); + + cfg = 0; + + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + cfg |= ATMEL_HLCDC_VSPOL; + + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + cfg |= ATMEL_HLCDC_HSPOL; + + regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5), + ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL | + ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE | + ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY | + ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO | + ATMEL_HLCDC_GUARDTIME_MASK, + cfg); + + fb = plane->fb; + plane->fb = old_fb; + + return atmel_hlcdc_plane_update_with_mode(plane, c, fb, 0, 0, + adj->hdisplay, adj->vdisplay, + x << 16, y << 16, + adj->hdisplay << 16, + adj->vdisplay << 16, + adj); +} + +int atmel_hlcdc_crtc_mode_set_base(struct drm_crtc *c, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_plane *plane = c->primary; + struct drm_framebuffer *fb = plane->fb; + struct drm_display_mode *mode = &c->hwmode; + + plane->fb = old_fb; + + return plane->funcs->update_plane(plane, c, fb, + 0, 0, + mode->hdisplay, + mode->vdisplay, + x << 16, y << 16, + mode->hdisplay << 16, + mode->vdisplay << 16); +} + +static void atmel_hlcdc_crtc_prepare(struct drm_crtc *crtc) +{ + atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); +} + +static void atmel_hlcdc_crtc_commit(struct drm_crtc *crtc) +{ + atmel_hlcdc_output_set_rgb_mode(crtc->dev); + atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON); +} + +static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adj) +{ + int timing; + + timing = adj->crtc_vsync_start - adj->crtc_vdisplay; + if (timing > 0x40) + adj->crtc_vsync_start = adj->crtc_vdisplay + 0x40; + else if (timing < 1) + adj->crtc_vsync_start = adj->crtc_vdisplay + 1; + + timing = adj->crtc_vsync_end - adj->crtc_vsync_start; + if (timing > 0x40) + adj->crtc_vsync_end = adj->crtc_vsync_start + 0x40; + else if (timing < 1) + adj->crtc_vsync_end = adj->crtc_vsync_start + 1; + + timing = adj->crtc_vtotal - adj->crtc_vsync_end; + if (timing > 0x3f) + adj->crtc_vtotal = adj->crtc_vsync_end + 0x3f; + else if (timing < 0) + adj->crtc_vtotal = adj->crtc_vsync_end; + + timing = adj->crtc_hsync_start - adj->crtc_hdisplay; + if (timing > 0x200) + adj->crtc_hsync_start = adj->crtc_hdisplay + 0x200; + else if (timing < 1) + adj->crtc_hsync_start = adj->crtc_hdisplay + 1; + + timing = adj->crtc_hsync_end - adj->crtc_hsync_start; + if (timing > 0x40) + adj->crtc_hsync_end = adj->crtc_hsync_start + 0x40; + else if (timing < 1) + adj->crtc_hsync_end = adj->crtc_hsync_start + 1; + + timing = adj->crtc_htotal - adj->crtc_hsync_end; + if (timing > 0x200) + adj->crtc_htotal = adj->crtc_hsync_end + 0x200; + else if (timing < 1) + adj->crtc_htotal = adj->crtc_hsync_end + 1; + + return true; +} + +static void atmel_hlcdc_crtc_disable(struct drm_crtc *crtc) +{ + struct drm_plane *plane; + + atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + crtc->primary->funcs->disable_plane(crtc->primary); + + drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) { + if (plane->crtc != crtc) + continue; + + plane->funcs->disable_plane(crtc->primary); + plane->crtc = NULL; + } +} + +static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = { + .mode_fixup = atmel_hlcdc_crtc_mode_fixup, + .dpms = atmel_hlcdc_crtc_dpms, + .mode_set = atmel_hlcdc_crtc_mode_set, + .mode_set_base = atmel_hlcdc_crtc_mode_set_base, + .prepare = atmel_hlcdc_crtc_prepare, + .commit = atmel_hlcdc_crtc_commit, + .disable = atmel_hlcdc_crtc_disable, +}; + +static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + + drm_crtc_cleanup(c); + kfree(crtc); +} + +void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *c, + struct drm_file *file) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + struct drm_pending_vblank_event *event; + struct drm_device *dev = c->dev; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + event = crtc->event; + if (event && event->base.file_priv == file) { + event->base.destroy(&event->base); + drm_vblank_put(dev, crtc->id); + crtc->event = NULL; + } + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + if (crtc->event) { + drm_send_vblank_event(dev, crtc->id, crtc->event); + drm_vblank_put(dev, crtc->id); + crtc->event = NULL; + } + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +void atmel_hlcdc_crtc_irq(struct drm_crtc *c) +{ + drm_handle_vblank(c->dev, 0); + atmel_hlcdc_crtc_finish_page_flip(drm_crtc_to_atmel_hlcdc_crtc(c)); +} + +static int atmel_hlcdc_crtc_page_flip(struct drm_crtc *c, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + struct atmel_hlcdc_plane_update_req req; + struct drm_plane *plane = c->primary; + struct drm_device *dev = c->dev; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&dev->event_lock, flags); + if (crtc->event) + ret = -EBUSY; + spin_unlock_irqrestore(&dev->event_lock, flags); + + if (ret) + return ret; + + memset(&req, 0, sizeof(req)); + req.crtc_x = 0; + req.crtc_y = 0; + req.crtc_h = c->mode.crtc_vdisplay; + req.crtc_w = c->mode.crtc_hdisplay; + req.src_x = c->x << 16; + req.src_y = c->y << 16; + req.src_w = req.crtc_w << 16; + req.src_h = req.crtc_h << 16; + req.fb = fb; + + ret = atmel_hlcdc_plane_prepare_update_req(plane, &req, &c->hwmode); + if (ret) + return ret; + + if (event) { + drm_vblank_get(c->dev, crtc->id); + spin_lock_irqsave(&dev->event_lock, flags); + crtc->event = event; + spin_unlock_irqrestore(&dev->event_lock, flags); + } + + ret = atmel_hlcdc_plane_apply_update_req(plane, &req); + if (ret) + crtc->event = NULL; + else + plane->fb = fb; + + return ret; +} + +static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = { + .page_flip = atmel_hlcdc_crtc_page_flip, + .set_config = drm_crtc_helper_set_config, + .destroy = atmel_hlcdc_crtc_destroy, +}; + +void atmel_hlcdc_crtc_suspend(struct drm_crtc *c) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + + if (crtc->dpms == DRM_MODE_DPMS_ON) { + atmel_hlcdc_crtc_dpms(c, DRM_MODE_DPMS_OFF); + /* save enable state for resume */ + crtc->dpms = DRM_MODE_DPMS_ON; + } +} + +void atmel_hlcdc_crtc_resume(struct drm_crtc *c) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + + if (crtc->dpms == DRM_MODE_DPMS_ON) { + crtc->dpms = DRM_MODE_DPMS_OFF; + atmel_hlcdc_crtc_dpms(c, DRM_MODE_DPMS_ON); + } +} + +int atmel_hlcdc_crtc_create(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + struct atmel_hlcdc_planes *planes = dc->planes; + struct atmel_hlcdc_crtc *crtc; + int ret; + int i; + + crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); + if (!crtc) + return -ENOMEM; + + crtc->dpms = DRM_MODE_DPMS_OFF; + crtc->dc = dc; + + ret = drm_crtc_init_with_planes(dev, &crtc->base, + &planes->primary->base, + planes->cursor ? &planes->cursor->base : NULL, + &atmel_hlcdc_crtc_funcs); + if (ret < 0) + goto fail; + + crtc->id = drm_crtc_index(&crtc->base); + + if (planes->cursor) + planes->cursor->base.possible_crtcs = 1 << crtc->id; + + for (i = 0; i < planes->noverlays; i++) + planes->overlays[i]->base.possible_crtcs = 1 << crtc->id; + + drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); + + dc->crtc = &crtc->base; + + return 0; + +fail: + atmel_hlcdc_crtc_destroy(&crtc->base); + return ret; +} + Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Traphandler + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com> + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/component.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> + +#include "atmel_hlcdc_dc.h" + +#define ATMEL_HLCDC_LAYER_IRQS_OFFSET 8 + +static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = { + { + .name = "base", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x40, + .id = 0, + .type = ATMEL_HLCDC_BASE_LAYER, + .nconfigs = 5, + .layout = { + .xstride = { 2 }, + .default_color = 3, + .general_config = 4, + }, + }, +}; + +static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = { + .min_width = 0, + .min_height = 0, + .max_width = 1280, + .max_height = 860, + .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers), + .layers = atmel_hlcdc_at91sam9n12_layers, +}; + +static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { + { + .name = "base", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x40, + .id = 0, + .type = ATMEL_HLCDC_BASE_LAYER, + .nconfigs = 5, + .layout = { + .xstride = { 2 }, + .default_color = 3, + .general_config = 4, + .disc_pos = 5, + .disc_size = 6, + }, + }, + { + .name = "overlay1", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x100, + .id = 1, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 10, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, + { + .name = "high-end-overlay", + .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats, + .regs_offset = 0x280, + .id = 2, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 17, + .layout = { + .pos = 2, + .size = 3, + .memsize = 4, + .xstride = { 5, 7 }, + .pstride = { 6, 8 }, + .default_color = 9, + .chroma_key = 10, + .chroma_key_mask = 11, + .general_config = 12, + .csc = 14, + }, + }, + { + .name = "cursor", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x340, + .id = 3, + .type = ATMEL_HLCDC_CURSOR_LAYER, + .nconfigs = 10, + .max_width = 128, + .max_height = 128, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, +}; + +static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = { + .min_width = 0, + .min_height = 0, + .max_width = 800, + .max_height = 600, + .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers), + .layers = atmel_hlcdc_at91sam9x5_layers, +}; + +static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { + { + .name = "base", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x40, + .id = 0, + .type = ATMEL_HLCDC_BASE_LAYER, + .nconfigs = 7, + .layout = { + .xstride = { 2 }, + .default_color = 3, + .general_config = 4, + .disc_pos = 5, + .disc_size = 6, + }, + }, + { + .name = "overlay1", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x140, + .id = 1, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 10, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, + { + .name = "overlay2", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x240, + .id = 2, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 10, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, + { + .name = "high-end-overlay", + .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats, + .regs_offset = 0x340, + .id = 3, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 42, + .layout = { + .pos = 2, + .size = 3, + .memsize = 4, + .xstride = { 5, 7 }, + .pstride = { 6, 8 }, + .default_color = 9, + .chroma_key = 10, + .chroma_key_mask = 11, + .general_config = 12, + .csc = 14, + }, + }, + { + .name = "cursor", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x440, + .id = 4, + .type = ATMEL_HLCDC_CURSOR_LAYER, + .nconfigs = 10, + .max_width = 128, + .max_height = 128, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, +}; + +static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = { + .min_width = 0, + .min_height = 0, + .max_width = 2048, + .max_height = 2048, + .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers), + .layers = atmel_hlcdc_sama5d3_layers, +}; + +static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { + { + .name = "base", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x40, + .id = 0, + .type = ATMEL_HLCDC_BASE_LAYER, + .nconfigs = 7, + .layout = { + .xstride = { 2 }, + .default_color = 3, + .general_config = 4, + .disc_pos = 5, + .disc_size = 6, + }, + }, + { + .name = "overlay1", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x140, + .id = 1, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 10, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, + { + .name = "overlay2", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x240, + .id = 2, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 10, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + }, + { + .name = "high-end-overlay", + .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats, + .regs_offset = 0x340, + .id = 3, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .nconfigs = 42, + .layout = { + .pos = 2, + .size = 3, + .memsize = 4, + .xstride = { 5, 7 }, + .pstride = { 6, 8 }, + .default_color = 9, + .chroma_key = 10, + .chroma_key_mask = 11, + .general_config = 12, + .csc = 14, + }, + }, +}; + +static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = { + .min_width = 0, + .min_height = 0, + .max_width = 2048, + .max_height = 2048, + .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers), + .layers = atmel_hlcdc_sama5d4_layers, +}; +static const struct of_device_id atmel_hlcdc_of_match[] = { + { + .compatible = "atmel,at91sam9n12-hlcdc", + .data = &atmel_hlcdc_dc_at91sam9n12, + }, + { + .compatible = "atmel,at91sam9x5-hlcdc", + .data = &atmel_hlcdc_dc_at91sam9x5, + }, + { + .compatible = "atmel,sama5d3-hlcdc", + .data = &atmel_hlcdc_dc_sama5d3, + }, + { + .compatible = "atmel,sama5d4-hlcdc", + .data = &atmel_hlcdc_dc_sama5d4, + }, + { /* sentinel */ }, +}; + +int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc, + struct drm_display_mode *mode) +{ + int vfront_porch = mode->crtc_vsync_start - mode->crtc_vdisplay; + int vback_porch = mode->crtc_vtotal - mode->crtc_vsync_end; + int vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; + int hfront_porch = mode->crtc_hsync_start - mode->crtc_hdisplay; + int hback_porch = mode->crtc_htotal - mode->crtc_hsync_end; + int hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + + if (hsync_len > 0x40 || hsync_len < 1) + return MODE_HSYNC; + + if (vsync_len > 0x40 || vsync_len < 1) + return MODE_VSYNC; + + if (hfront_porch > 0x200 || hfront_porch < 1 || + hback_porch > 0x200 || hback_porch < 1 || + mode->crtc_hdisplay < 1) + return MODE_H_ILLEGAL; + + if (vfront_porch > 0x40 || vfront_porch < 1 || + vback_porch > 0x40 || vback_porch < 0 || + mode->crtc_vdisplay < 1) + return MODE_V_ILLEGAL; + + return MODE_OK; +} + +static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data) +{ + struct drm_device *dev = data; + struct atmel_hlcdc_dc *dc = dev->dev_private; + unsigned long status; + unsigned int imr, isr; + int i; + + regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_IMR, &imr); + regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr); + status = imr & isr; + if (!status) + return IRQ_NONE; + + if (status & ATMEL_HLCDC_SOF) + atmel_hlcdc_crtc_irq(dc->crtc); + + for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) { + struct atmel_hlcdc_layer *layer = dc->layers[i]; + + if (!(ATMEL_HLCDC_LAYER_STATUS(i) & status) || !layer) + continue; + + atmel_hlcdc_layer_irq(layer); + } + + return IRQ_HANDLED; +} + +static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev, + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) +{ + return drm_fb_cma_create(dev, file_priv, mode_cmd); +} + +static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + + if (dc->fbdev) { + drm_fbdev_cma_hotplug_event(dc->fbdev); + } else { + dc->fbdev = drm_fbdev_cma_init(dev, 24, + dev->mode_config.num_crtc, + dev->mode_config.num_connector); + if (IS_ERR(dc->fbdev)) + dc->fbdev = NULL; + } +} + +static const struct drm_mode_config_funcs mode_config_funcs = { + .fb_create = atmel_hlcdc_fb_create, + .output_poll_changed = atmel_hlcdc_fb_output_poll_changed, +}; + +static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + struct atmel_hlcdc_planes *planes; + int ret; + int i; + +// ret = atmel_hlcdc_create_outputs(dev); +// if (ret) +// return ret; + + planes = atmel_hlcdc_create_planes(dev); + if (IS_ERR(planes)) { + dev_err(dev->dev, "failed to create planes\n"); + ret = PTR_ERR(planes); + goto err_destroy_outputs; + } + + dc->planes = planes; + + dc->layers[planes->primary->layer.desc->id] = + &planes->primary->layer; + + if (planes->cursor) + dc->layers[planes->cursor->layer.desc->id] = + &planes->cursor->layer; + + for (i = 0; i < planes->noverlays; i++) + dc->layers[planes->overlays[i]->layer.desc->id] = + &planes->overlays[i]->layer; + + ret = atmel_hlcdc_crtc_create(dev); + if (ret) { + dev_err(dev->dev, "failed to create crtc\n"); + goto err_destroy_outputs; + } + + dev->mode_config.min_width = dc->desc->min_width; + dev->mode_config.min_height = dc->desc->min_height; + dev->mode_config.max_width = dc->desc->max_width; + dev->mode_config.max_height = dc->desc->max_height; + dev->mode_config.funcs = &mode_config_funcs; + + return 0; + +err_destroy_outputs: + atmel_hlcdc_destroy_outputs(dev); + + return ret; +} + +static int atmel_hlcdc_dc_load(struct drm_device *dev) +{ + struct platform_device *pdev = to_platform_device(dev->dev); + const struct of_device_id *match; + struct atmel_hlcdc_dc *dc; + int ret; + + match = of_match_node(atmel_hlcdc_of_match, dev->dev->parent->of_node); + if (!match) { + dev_err(&pdev->dev, "invalid compatible string\n"); + return -ENODEV; + } + + if (!match->data) { + dev_err(&pdev->dev, "invalid hlcdc description\n"); + return -EINVAL; + } + + dc = devm_kzalloc(dev->dev, sizeof(*dc), GFP_KERNEL); + if (!dc) + return -ENOMEM; + + dc->wq = alloc_ordered_workqueue("atmel-hlcdc-dc", 0); + if (!dc->wq) + return -ENOMEM; + + dc->desc = match->data; + dc->hlcdc = dev_get_drvdata(dev->dev->parent); + dev->dev_private = dc; + + ret = clk_prepare_enable(dc->hlcdc->periph_clk); + if (ret) { + dev_err(dev->dev, "failed to enable periph_clk\n"); + goto err_destroy_wq; + } + + pm_runtime_enable(dev->dev); + + ret = atmel_hlcdc_dc_modeset_init(dev); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize mode setting\n"); + goto err_periph_clk_disable; + } + + ret = drm_vblank_init(dev, 1); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize vblank\n"); + goto err_periph_clk_disable; + } + + pm_runtime_get_sync(dev->dev); + ret = drm_irq_install(dev, dc->hlcdc->irq); + pm_runtime_put_sync(dev->dev); + if (ret < 0) { + dev_err(dev->dev, "failed to install IRQ handler\n"); + goto err_periph_clk_disable; + } + + drm_kms_helper_poll_init(dev); + + /* force connectors detection */ + drm_helper_hpd_irq_event(dev); + + return 0; + +err_periph_clk_disable: + pm_runtime_disable(dev->dev); + clk_disable_unprepare(dc->hlcdc->periph_clk); + +err_destroy_wq: + destroy_workqueue(dc->wq); + + return ret; +} + +static void atmel_hlcdc_dc_unload(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + + if (!dc) + return; + + if (dc->fbdev) + drm_fbdev_cma_fini(dc->fbdev); + flush_workqueue(dc->wq); + drm_kms_helper_poll_fini(dev); + drm_vblank_cleanup(dev); + + pm_runtime_get_sync(dev->dev); + drm_irq_uninstall(dev); + pm_runtime_put_sync(dev->dev); + + atmel_hlcdc_destroy_outputs(dev); + dev->dev_private = NULL; + + pm_runtime_disable(dev->dev); + clk_disable_unprepare(dc->hlcdc->periph_clk); + destroy_workqueue(dc->wq); + + dev->dev_private = NULL; +} + +static int atmel_hlcdc_dc_connector_plug_all(struct drm_device *dev) +{ + struct drm_connector *connector, *failed; + int ret; + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + ret = drm_connector_register(connector); + if (ret) { + failed = connector; + goto err; + } + } + mutex_unlock(&dev->mode_config.mutex); + return 0; + +err: + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (failed == connector) + break; + + drm_connector_unregister(connector); + } + mutex_unlock(&dev->mode_config.mutex); + + return ret; +} + +static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev) +{ + mutex_lock(&dev->mode_config.mutex); + drm_connector_unplug_all(dev); + mutex_unlock(&dev->mode_config.mutex); +} + +static void atmel_hlcdc_dc_preclose(struct drm_device *dev, + struct drm_file *file) +{ + struct drm_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + atmel_hlcdc_crtc_cancel_page_flip(crtc, file); +} + +static void atmel_hlcdc_dc_lastclose(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + + drm_fbdev_cma_restore_mode(dc->fbdev); +} + +static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + unsigned int cfg = 0; + int i; + + /* Enable interrupts on activated layers */ + for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) { + if (dc->layers[i]) + cfg |= ATMEL_HLCDC_LAYER_STATUS(i); + } + + regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg); + + return 0; +} + +static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + unsigned int isr; + + regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff); + regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr); +} + +static int atmel_hlcdc_dc_enable_vblank(struct drm_device *dev, int crtc) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + + /* Enable SOF (Start Of Frame) interrupt for vblank counting */ + regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, ATMEL_HLCDC_SOF); + + return 0; +} + +static void atmel_hlcdc_dc_disable_vblank(struct drm_device *dev, int crtc) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + + regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, ATMEL_HLCDC_SOF); +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .poll = drm_poll, + .read = drm_read, + .llseek = no_llseek, + .mmap = drm_gem_cma_mmap, +}; + +static struct drm_driver atmel_hlcdc_dc_driver = { + .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, + .preclose = atmel_hlcdc_dc_preclose, + .lastclose = atmel_hlcdc_dc_lastclose, + .irq_handler = atmel_hlcdc_dc_irq_handler, + .irq_preinstall = atmel_hlcdc_dc_irq_uninstall, + .irq_postinstall = atmel_hlcdc_dc_irq_postinstall, + .irq_uninstall = atmel_hlcdc_dc_irq_uninstall, + .get_vblank_counter = drm_vblank_count, + .enable_vblank = atmel_hlcdc_dc_enable_vblank, + .disable_vblank = atmel_hlcdc_dc_disable_vblank, + .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_dumb_destroy, + .fops = &fops, + .name = "atmel-hlcdc", + .desc = "Atmel HLCD Controller DRM", + .date = "20141504", + .major = 1, + .minor = 0, +}; + +static int atmel_hlcdc_init(struct drm_device *ddev) +{ + int ret; + + ret = atmel_hlcdc_create_outputs(ddev); + if (ret) + return ret; + + ret = atmel_hlcdc_dc_load(ddev); + if (ret) + goto err_destroy_outputs; + + ret = drm_dev_register(ddev, 0); + if (ret) + goto err_unload; + + ret = atmel_hlcdc_dc_connector_plug_all(ddev); + if (ret) + goto err_unregister; + + return 0; + +err_unregister: + drm_dev_unregister(ddev); + +err_unload: + atmel_hlcdc_dc_unload(ddev); + +err_destroy_outputs: + atmel_hlcdc_destroy_outputs(ddev); + + return ret; +} + +static void atmel_hlcdc_cleanup(struct drm_device *ddev) +{ + atmel_hlcdc_dc_connector_unplug_all(ddev); + drm_dev_unregister(ddev); + atmel_hlcdc_dc_unload(ddev); + atmel_hlcdc_destroy_outputs(ddev); +} + +static int atmel_hlcdc_output_bind(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + int ret; + + ret = component_bind_all(dev, ddev); + if (ret) + return ret; + + ret = atmel_hlcdc_init(ddev); + if (ret) { + component_unbind_all(dev, ddev); + return ret; + } else { + dev_info(ddev->dev, "DRM device successfully registered"); + } + + return 0; +} + +static void atmel_hlcdc_output_unbind(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + + atmel_hlcdc_cleanup(ddev); + component_unbind_all(dev, ddev); +} + +static const struct component_master_ops atmel_hlcdc_output_master_ops = { + .bind = atmel_hlcdc_output_bind, + .unbind = atmel_hlcdc_output_unbind, +}; + +static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) +{ + struct component_match *match = NULL; + struct drm_device *ddev; + int ret; + + if (!atmel_hlcdc_output_panels_ready(&pdev->dev)) + return -EPROBE_DEFER; + + ddev = drm_dev_alloc(&atmel_hlcdc_dc_driver, &pdev->dev); + if (!ddev) + return -ENOMEM; + + ret = drm_dev_set_unique(ddev, dev_name(ddev->dev)); + if (ret) { + drm_dev_unref(ddev); + return ret; + } + + drm_mode_config_init(ddev); + + platform_set_drvdata(pdev, ddev); + + ret = atmel_hlcdc_find_output_components(&pdev->dev, &match); + if (ret) + goto err_unref; + + if (!match) { + ret = atmel_hlcdc_init(ddev); + if (!ret) + dev_info(ddev->dev, + "DRM device successfully registered"); + } else { + ret = component_master_add_with_match(&pdev->dev, + &atmel_hlcdc_output_master_ops, + match); + } + + if (ret) + goto err_unref; + + return 0; + +err_unref: + drm_dev_unref(ddev); + + return ret; +} + +static int atmel_hlcdc_dc_drm_remove(struct platform_device *pdev) +{ + struct drm_device *ddev = platform_get_drvdata(pdev); + + component_master_del(&pdev->dev, &atmel_hlcdc_output_master_ops); + + if (ddev->dev_private) + atmel_hlcdc_cleanup(ddev); + + drm_mode_config_cleanup(ddev); + drm_dev_unref(ddev); + + return 0; +} + +#ifdef CONFIG_PM +static int atmel_hlcdc_dc_drm_suspend(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + struct drm_crtc *crtc; + + if (pm_runtime_suspended(dev)) + return 0; + + drm_modeset_lock_all(drm_dev); + list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) + atmel_hlcdc_crtc_suspend(crtc); + drm_modeset_unlock_all(drm_dev); + return 0; +} + +static int atmel_hlcdc_dc_drm_resume(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + struct drm_crtc *crtc; + + if (pm_runtime_suspended(dev)) + return 0; + + drm_modeset_lock_all(drm_dev); + list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) + atmel_hlcdc_crtc_resume(crtc); + drm_modeset_unlock_all(drm_dev); + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(atmel_hlcdc_dc_drm_pm_ops, + atmel_hlcdc_dc_drm_suspend, atmel_hlcdc_dc_drm_resume); + +static const struct of_device_id atmel_hlcdc_dc_of_match[] = { + { .compatible = "atmel,hlcdc-display-controller" }, + { }, +}; + +static struct platform_driver atmel_hlcdc_dc_platform_driver = { + .probe = atmel_hlcdc_dc_drm_probe, + .remove = atmel_hlcdc_dc_drm_remove, + .driver = { + .name = "atmel-hlcdc-display-controller", + .pm = &atmel_hlcdc_dc_drm_pm_ops, + .of_match_table = atmel_hlcdc_dc_of_match, + }, +}; +module_platform_driver(atmel_hlcdc_dc_platform_driver); + +MODULE_AUTHOR("Jean-Jacques Hiblot <jjhiblot@traphandler.com>"); +MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); +MODULE_DESCRIPTION("Atmel HLCDC Display Controller DRM Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:atmel-hlcdc-dc"); Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Traphandler + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com> + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DRM_ATMEL_HLCDC_H +#define DRM_ATMEL_HLCDC_H + +#include <linux/clk.h> +#include <linux/component.h> +#include <linux/irqdomain.h> +#include <linux/pwm.h> + +#include <drm/drm_crtc.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_cma_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_panel.h> +#include <drm/drmP.h> + +#include "atmel_hlcdc_layer.h" + +#define ATMEL_HLCDC_MAX_LAYERS 5 + +/** + * Atmel HLCDC Display Controller description structure. + * + * This structure describe the HLCDC IP capabilities and depends on the + * HLCDC IP version (or Atmel SoC family). + * + * @min_width: minimum width supported by the Display Controller + * @min_height: minimum height supported by the Display Controller + * @max_width: maximum width supported by the Display Controller + * @max_height: maximum height supported by the Display Controller + * @layers: a layer description table describing available layers + * @nlayers: layer description table size + */ +struct atmel_hlcdc_dc_desc { + int min_width; + int min_height; + int max_width; + int max_height; + const struct atmel_hlcdc_layer_desc *layers; + int nlayers; +}; + +/** + * Atmel HLCDC Plane properties. + * + * This structure stores plane property definitions. + * + * @alpha: alpha blending (or transparency) property + * @rotation: rotation property + */ +struct atmel_hlcdc_plane_properties { + struct drm_property *alpha; + struct drm_property *rotation; +}; + +/** + * Atmel HLCDC Plane. + * + * @base: base DRM plane structure + * @layer: HLCDC layer structure + * @properties: pointer to the property definitions structure + * @rotation: current rotation status + */ +struct atmel_hlcdc_plane { + struct drm_plane base; + struct atmel_hlcdc_layer layer; + struct atmel_hlcdc_plane_properties *properties; + unsigned int rotation; +}; + +static inline struct atmel_hlcdc_plane * +drm_plane_to_atmel_hlcdc_plane(struct drm_plane *p) +{ + return container_of(p, struct atmel_hlcdc_plane, base); +} + +static inline struct atmel_hlcdc_plane * +atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *l) +{ + return container_of(l, struct atmel_hlcdc_plane, layer); +} + +/** + * Atmel HLCDC Plane update request structure. + * + * @crtc_x: x position of the plane relative to the CRTC + * @crtc_y: y position of the plane relative to the CRTC + * @crtc_w: visible width of the plane + * @crtc_h: visible height of the plane + * @src_x: x buffer position + * @src_y: y buffer position + * @src_w: buffer width + * @src_h: buffer height + * @fb: framebuffer object object + * @bpp: bytes per pixel deduced from pixel_format + * @offsets: offsets to apply to the GEM buffers + * @xstride: value to add to the pixel pointer between each line + * @pstride: value to add to the pixel pointer between each pixel + * @nplanes: number of planes (deduced from pixel_format) + */ +struct atmel_hlcdc_plane_update_req { + int crtc_x; + int crtc_y; + unsigned int crtc_w; + unsigned int crtc_h; + uint32_t src_x; + uint32_t src_y; + uint32_t src_w; + uint32_t src_h; + struct drm_framebuffer *fb; + + /* These fields are private and should not be touched */ + int bpp[ATMEL_HLCDC_MAX_PLANES]; + unsigned int offsets[ATMEL_HLCDC_MAX_PLANES]; + int xstride[ATMEL_HLCDC_MAX_PLANES]; + int pstride[ATMEL_HLCDC_MAX_PLANES]; + int nplanes; +}; + +/** + * Atmel HLCDC Planes. + * + * This structure stores the instantiated HLCDC Planes and can be accessed by + * the HLCDC Display Controller or the HLCDC CRTC. + * + * @primary: primary plane + * @cursor: hardware cursor plane + * @overlays: overlay plane table + * @noverlays: number of overlay planes + */ +struct atmel_hlcdc_planes { + struct atmel_hlcdc_plane *primary; + struct atmel_hlcdc_plane *cursor; + struct atmel_hlcdc_plane **overlays; + int noverlays; +}; + +/** + * Atmel HLCDC Display Controller. + * + * @desc: HLCDC Display Controller description + * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device + * @fbdev: framebuffer device attached to the Display Controller + * @crtc: CRTC provided by the display controller + * @planes: instantiated planes + * @layers: active HLCDC layer + * @wq: display controller workqueue + */ +struct atmel_hlcdc_dc { + const struct atmel_hlcdc_dc_desc *desc; + struct atmel_hlcdc *hlcdc; + struct drm_fbdev_cma *fbdev; + struct drm_crtc *crtc; + struct atmel_hlcdc_planes *planes; + struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS]; + struct workqueue_struct *wq; +}; + +extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats; +extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats; + +int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc, + struct drm_display_mode *mode); + +struct atmel_hlcdc_planes * +atmel_hlcdc_create_planes(struct drm_device *dev); + +int atmel_hlcdc_plane_prepare_update_req(struct drm_plane *p, + struct atmel_hlcdc_plane_update_req *req, + const struct drm_display_mode *mode); + +int atmel_hlcdc_plane_apply_update_req(struct drm_plane *p, + struct atmel_hlcdc_plane_update_req *req); + +int atmel_hlcdc_plane_update_with_mode(struct drm_plane *p, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, + unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + const struct drm_display_mode *mode); + +void atmel_hlcdc_crtc_irq(struct drm_crtc *c); + +void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, + struct drm_file *file); + +void atmel_hlcdc_crtc_suspend(struct drm_crtc *crtc); +void atmel_hlcdc_crtc_resume(struct drm_crtc *crtc); + +int atmel_hlcdc_crtc_create(struct drm_device *dev); + +int atmel_hlcdc_output_set_rgb_mode(struct drm_device *dev); + +int atmel_hlcdc_create_outputs(struct drm_device *dev); + +void atmel_hlcdc_destroy_outputs(struct drm_device *dev); + +bool atmel_hlcdc_output_panels_ready(struct device *dev); + +int atmel_hlcdc_find_output_components(struct device *dev, + struct component_match **match); + +#endif /* DRM_ATMEL_HLCDC_H */ Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> + +#include "atmel_hlcdc_dc.h" + +static void +atmel_hlcdc_layer_fb_flip_release(struct drm_flip_work *work, void *val) +{ + struct atmel_hlcdc_layer_fb_flip *flip = val; + + if (flip->fb) + drm_framebuffer_unreference(flip->fb); + kfree(flip); +} + +static void +atmel_hlcdc_layer_fb_flip_destroy(struct atmel_hlcdc_layer_fb_flip *flip) +{ + if (flip->fb) + drm_framebuffer_unreference(flip->fb); + kfree(flip->task); + kfree(flip); +} + +static void +atmel_hlcdc_layer_fb_flip_release_queue(struct atmel_hlcdc_layer *layer, + struct atmel_hlcdc_layer_fb_flip *flip) +{ + int i; + + if (!flip) + return; + + for (i = 0; i < layer->max_planes; i++) { + if (!flip->dscrs[i]) + break; + + flip->dscrs[i]->status = 0; + flip->dscrs[i] = NULL; + } + + drm_flip_work_queue_task(&layer->gc, flip->task); + drm_flip_work_commit(&layer->gc, layer->wq); +} + +static void atmel_hlcdc_layer_update_reset(struct atmel_hlcdc_layer *layer, + int id) +{ + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct atmel_hlcdc_layer_update_slot *slot; + + if (id < 0 || id > 1) + return; + + slot = &upd->slots[id]; + bitmap_clear(slot->updated_configs, 0, layer->desc->nconfigs); + memset(slot->configs, 0, + sizeof(*slot->configs) * layer->desc->nconfigs); + + if (slot->fb_flip) { + atmel_hlcdc_layer_fb_flip_release_queue(layer, slot->fb_flip); + slot->fb_flip = NULL; + } +} + +static void atmel_hlcdc_layer_update_apply(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + const struct atmel_hlcdc_layer_desc *desc = layer->desc; + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct regmap *regmap = layer->hlcdc->regmap; + struct atmel_hlcdc_layer_update_slot *slot; + struct atmel_hlcdc_layer_fb_flip *fb_flip; + struct atmel_hlcdc_dma_channel_dscr *dscr; + unsigned int cfg; + u32 action = 0; + int i = 0; + + if (upd->pending < 0 || upd->pending > 1) + return; + + slot = &upd->slots[upd->pending]; + + for_each_set_bit(cfg, slot->updated_configs, layer->desc->nconfigs) { + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_CFG(layer, cfg), + slot->configs[cfg]); + action |= ATMEL_HLCDC_LAYER_UPDATE; + } + + fb_flip = slot->fb_flip; + + if (!fb_flip->fb) + goto apply; + + if (dma->status == ATMEL_HLCDC_LAYER_DISABLED) { + for (i = 0; i < fb_flip->ngems; i++) { + dscr = fb_flip->dscrs[i]; + dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH | + ATMEL_HLCDC_LAYER_DMA_IRQ | + ATMEL_HLCDC_LAYER_ADD_IRQ | + ATMEL_HLCDC_LAYER_DONE_IRQ; + + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_PLANE_ADDR(i), + dscr->addr); + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_PLANE_CTRL(i), + dscr->ctrl); + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_PLANE_NEXT(i), + dscr->next); + } + + action |= ATMEL_HLCDC_LAYER_DMA_CHAN; + dma->status = ATMEL_HLCDC_LAYER_ENABLED; + } else { + for (i = 0; i < fb_flip->ngems; i++) { + dscr = fb_flip->dscrs[i]; + dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH | + ATMEL_HLCDC_LAYER_DMA_IRQ | + ATMEL_HLCDC_LAYER_DSCR_IRQ | + ATMEL_HLCDC_LAYER_DONE_IRQ; + + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_PLANE_HEAD(i), + dscr->next); + } + + action |= ATMEL_HLCDC_LAYER_A2Q; + } + + /* Release unneeded descriptors */ + for (i = fb_flip->ngems; i < layer->max_planes; i++) { + fb_flip->dscrs[i]->status = 0; + fb_flip->dscrs[i] = NULL; + } + + dma->queue = fb_flip; + slot->fb_flip = NULL; + +apply: + if (action) + regmap_write(regmap, + desc->regs_offset + ATMEL_HLCDC_LAYER_CHER, + action); + + atmel_hlcdc_layer_update_reset(layer, upd->pending); + + upd->pending = -1; +} + +void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + const struct atmel_hlcdc_layer_desc *desc = layer->desc; + struct regmap *regmap = layer->hlcdc->regmap; + struct atmel_hlcdc_layer_fb_flip *flip; + unsigned long flags; + unsigned int isr, imr; + unsigned int status; + unsigned int plane_status; + u32 flip_status; + + int i; + + regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IMR, &imr); + regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr); + status = imr & isr; + if (!status) + return; + + spin_lock_irqsave(&layer->lock, flags); + + flip = dma->queue ? dma->queue : dma->cur; + + if (!flip) { + spin_unlock_irqrestore(&layer->lock, flags); + return; + } + + /* + * Set LOADED and DONE flags: they'll be cleared if at least one + * memory plane is not LOADED or DONE. + */ + flip_status = ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED | + ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE; + for (i = 0; i < flip->ngems; i++) { + plane_status = (status >> (8 * i)); + + if (plane_status & + (ATMEL_HLCDC_LAYER_ADD_IRQ | + ATMEL_HLCDC_LAYER_DSCR_IRQ) & + ~flip->dscrs[i]->ctrl) { + flip->dscrs[i]->status |= + ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED; + flip->dscrs[i]->ctrl |= + ATMEL_HLCDC_LAYER_ADD_IRQ | + ATMEL_HLCDC_LAYER_DSCR_IRQ; + } + + if (plane_status & + ATMEL_HLCDC_LAYER_DONE_IRQ & + ~flip->dscrs[i]->ctrl) { + flip->dscrs[i]->status |= + ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE; + flip->dscrs[i]->ctrl |= + ATMEL_HLCDC_LAYER_DONE_IRQ; + } + + if (plane_status & ATMEL_HLCDC_LAYER_OVR_IRQ) + flip->dscrs[i]->status |= + ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN; + + /* + * Clear LOADED and DONE flags if the memory plane is either + * not LOADED or not DONE. + */ + if (!(flip->dscrs[i]->status & + ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED)) + flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED; + + if (!(flip->dscrs[i]->status & + ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE)) + flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE; + + /* + * An overrun on one memory plane impact the whole framebuffer + * transfer, hence we set the OVERRUN flag as soon as there's + * one memory plane reporting such an overrun. + */ + flip_status |= flip->dscrs[i]->status & + ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN; + } + + /* Get changed bits */ + flip_status ^= flip->status; + flip->status |= flip_status; + + if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED) { + atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur); + dma->cur = dma->queue; + dma->queue = NULL; + } + + if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE) { + atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur); + dma->cur = NULL; + } + + if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN) { + regmap_write(regmap, + desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR, + ATMEL_HLCDC_LAYER_RST); + if (dma->queue) + atmel_hlcdc_layer_fb_flip_release_queue(layer, + dma->queue); + + if (dma->cur) + atmel_hlcdc_layer_fb_flip_release_queue(layer, + dma->cur); + + dma->cur = NULL; + dma->queue = NULL; + } + + if (!dma->queue) { + atmel_hlcdc_layer_update_apply(layer); + + if (!dma->cur) + dma->status = ATMEL_HLCDC_LAYER_DISABLED; + } + + spin_unlock_irqrestore(&layer->lock, flags); +} + +int atmel_hlcdc_layer_disable(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct regmap *regmap = layer->hlcdc->regmap; + const struct atmel_hlcdc_layer_desc *desc = layer->desc; + unsigned long flags; + unsigned int isr; + + spin_lock_irqsave(&layer->lock, flags); + + /* Disable the layer */ + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR, + ATMEL_HLCDC_LAYER_RST | ATMEL_HLCDC_LAYER_A2Q | + ATMEL_HLCDC_LAYER_UPDATE); + + /* Clear all pending interrupts */ + regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr); + + /* Discard current and queued framebuffer transfers. */ + if (dma->cur) { + atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur); + dma->cur = NULL; + } + + if (dma->queue) { + atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->queue); + dma->queue = NULL; + } + + /* + * Then discard the pending update request (if any) to prevent + * DMA irq handler from restarting the DMA channel after it has + * been disabled. + */ + if (upd->pending >= 0) { + atmel_hlcdc_layer_update_reset(layer, upd->pending); + upd->pending = -1; + } + + dma->status = ATMEL_HLCDC_LAYER_DISABLED; + + spin_unlock_irqrestore(&layer->lock, flags); + + return 0; +} + +int atmel_hlcdc_layer_update_start(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct regmap *regmap = layer->hlcdc->regmap; + struct atmel_hlcdc_layer_fb_flip *fb_flip; + struct atmel_hlcdc_layer_update_slot *slot; + unsigned long flags; + int i, j = 0; + + fb_flip = kzalloc(sizeof(*fb_flip), GFP_KERNEL); + if (!fb_flip) + return -ENOMEM; + + fb_flip->task = drm_flip_work_allocate_task(fb_flip, GFP_KERNEL); + if (!fb_flip->task) { + kfree(fb_flip); + return -ENOMEM; + } + + spin_lock_irqsave(&layer->lock, flags); + + upd->next = upd->pending ? 0 : 1; + + slot = &upd->slots[upd->next]; + + for (i = 0; i < layer->max_planes * 4; i++) { + if (!dma->dscrs[i].status) { + fb_flip->dscrs[j++] = &dma->dscrs[i]; + dma->dscrs[i].status = + ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED; + if (j == layer->max_planes) + break; + } + } + + if (j < layer->max_planes) { + for (i = 0; i < j; i++) + fb_flip->dscrs[i]->status = 0; + } + + if (j < layer->max_planes) { + spin_unlock_irqrestore(&layer->lock, flags); + atmel_hlcdc_layer_fb_flip_destroy(fb_flip); + return -EBUSY; + } + + slot->fb_flip = fb_flip; + + if (upd->pending >= 0) { + memcpy(slot->configs, + upd->slots[upd->pending].configs, + layer->desc->nconfigs * sizeof(u32)); + memcpy(slot->updated_configs, + upd->slots[upd->pending].updated_configs, + DIV_ROUND_UP(layer->desc->nconfigs, + BITS_PER_BYTE * sizeof(unsigned long)) * + sizeof(unsigned long)); + slot->fb_flip->fb = upd->slots[upd->pending].fb_flip->fb; + if (upd->slots[upd->pending].fb_flip->fb) { + slot->fb_flip->fb = + upd->slots[upd->pending].fb_flip->fb; + slot->fb_flip->ngems = + upd->slots[upd->pending].fb_flip->ngems; + drm_framebuffer_reference(slot->fb_flip->fb); + } + } else { + regmap_bulk_read(regmap, + layer->desc->regs_offset + + ATMEL_HLCDC_LAYER_CFG(layer, 0), + upd->slots[upd->next].configs, + layer->desc->nconfigs); + } + + spin_unlock_irqrestore(&layer->lock, flags); + + return 0; +} + +void atmel_hlcdc_layer_update_rollback(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_update *upd = &layer->update; + + atmel_hlcdc_layer_update_reset(layer, upd->next); + upd->next = -1; +} + +void atmel_hlcdc_layer_update_set_fb(struct atmel_hlcdc_layer *layer, + struct drm_framebuffer *fb, + unsigned int *offsets) +{ + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct atmel_hlcdc_layer_fb_flip *fb_flip; + struct atmel_hlcdc_layer_update_slot *slot; + struct atmel_hlcdc_dma_channel_dscr *dscr; + struct drm_framebuffer *old_fb; + int nplanes = 0; + int i; + + if (upd->next < 0 || upd->next > 1) + return; + + if (fb) + nplanes = drm_format_num_planes(fb->pixel_format); + + if (nplanes > layer->max_planes) + return; + + slot = &upd->slots[upd->next]; + + fb_flip = slot->fb_flip; + old_fb = slot->fb_flip->fb; + + for (i = 0; i < nplanes; i++) { + struct drm_gem_cma_object *gem; + + dscr = slot->fb_flip->dscrs[i]; + gem = drm_fb_cma_get_gem_obj(fb, i); + dscr->addr = gem->paddr + offsets[i]; + } + + fb_flip->ngems = nplanes; + fb_flip->fb = fb; + + if (fb) + drm_framebuffer_reference(fb); + + if (old_fb) + drm_framebuffer_unreference(old_fb); +} + +void atmel_hlcdc_layer_update_cfg(struct atmel_hlcdc_layer *layer, int cfg, + u32 mask, u32 val) +{ + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct atmel_hlcdc_layer_update_slot *slot; + + if (upd->next < 0 || upd->next > 1) + return; + + if (cfg >= layer->desc->nconfigs) + return; + + slot = &upd->slots[upd->next]; + slot->configs[cfg] &= ~mask; + slot->configs[cfg] |= (val & mask); + set_bit(cfg, slot->updated_configs); +} + +void atmel_hlcdc_layer_update_commit(struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + struct atmel_hlcdc_layer_update *upd = &layer->update; + struct atmel_hlcdc_layer_update_slot *slot; + unsigned long flags; + + if (upd->next < 0 || upd->next > 1) + return; + + slot = &upd->slots[upd->next]; + + spin_lock_irqsave(&layer->lock, flags); + + /* + * Release pending update request and replace it by the new one. + */ + if (upd->pending >= 0) + atmel_hlcdc_layer_update_reset(layer, upd->pending); + + upd->pending = upd->next; + upd->next = -1; + + if (!dma->queue) + atmel_hlcdc_layer_update_apply(layer); + + spin_unlock_irqrestore(&layer->lock, flags); + + + upd->next = -1; +} + +static int atmel_hlcdc_layer_dma_init(struct drm_device *dev, + struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + dma_addr_t dma_addr; + int i; + + dma->dscrs = dma_alloc_coherent(dev->dev, + layer->max_planes * 4 * + sizeof(*dma->dscrs), + &dma_addr, GFP_KERNEL); + if (!dma->dscrs) + return -ENOMEM; + + for (i = 0; i < layer->max_planes * 4; i++) { + struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i]; + + dscr->next = dma_addr + (i * sizeof(*dscr)); + } + + return 0; +} + +static void atmel_hlcdc_layer_dma_cleanup(struct drm_device *dev, + struct atmel_hlcdc_layer *layer) +{ + struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma; + int i; + + for (i = 0; i < layer->max_planes * 4; i++) { + struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i]; + + dscr->status = 0; + } + + dma_free_coherent(dev->dev, layer->max_planes * 4 * + sizeof(*dma->dscrs), dma->dscrs, + dma->dscrs[0].next); +} + +static int atmel_hlcdc_layer_update_init(struct drm_device *dev, + struct atmel_hlcdc_layer *layer, + const struct atmel_hlcdc_layer_desc *desc) +{ + struct atmel_hlcdc_layer_update *upd = &layer->update; + int updated_size; + void *buffer; + int i; + + updated_size = DIV_ROUND_UP(desc->nconfigs, + BITS_PER_BYTE * + sizeof(unsigned long)); + + buffer = devm_kzalloc(dev->dev, + ((desc->nconfigs * sizeof(u32)) + + (updated_size * sizeof(unsigned long))) * 2, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + for (i = 0; i < 2; i++) { + upd->slots[i].updated_configs = buffer; + buffer += updated_size * sizeof(unsigned long); + upd->slots[i].configs = buffer; + buffer += desc->nconfigs * sizeof(u32); + } + + upd->pending = -1; + upd->next = -1; + + return 0; +} + +int atmel_hlcdc_layer_init(struct drm_device *dev, + struct atmel_hlcdc_layer *layer, + const struct atmel_hlcdc_layer_desc *desc) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + struct regmap *regmap = dc->hlcdc->regmap; + unsigned int tmp; + int ret; + int i; + + layer->hlcdc = dc->hlcdc; + layer->wq = dc->wq; + layer->desc = desc; + + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR, + ATMEL_HLCDC_LAYER_RST); + for (i = 0; i < desc->formats->nformats; i++) { + int nplanes = drm_format_num_planes(desc->formats->formats[i]); + + if (nplanes > layer->max_planes) + layer->max_planes = nplanes; + } + + spin_lock_init(&layer->lock); + drm_flip_work_init(&layer->gc, desc->name, + atmel_hlcdc_layer_fb_flip_release); + ret = atmel_hlcdc_layer_dma_init(dev, layer); + if (ret) + return ret; + + ret = atmel_hlcdc_layer_update_init(dev, layer, desc); + if (ret) + return ret; + + /* Flush Status Register */ + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR, + 0xffffffff); + regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, + &tmp); + + tmp = 0; + for (i = 0; i < layer->max_planes; i++) + tmp |= (ATMEL_HLCDC_LAYER_DMA_IRQ | + ATMEL_HLCDC_LAYER_DSCR_IRQ | + ATMEL_HLCDC_LAYER_ADD_IRQ | + ATMEL_HLCDC_LAYER_DONE_IRQ | + ATMEL_HLCDC_LAYER_OVR_IRQ) << (8 * i); + + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IER, tmp); + + return 0; +} + +void atmel_hlcdc_layer_cleanup(struct drm_device *dev, + struct atmel_hlcdc_layer *layer) +{ + const struct atmel_hlcdc_layer_desc *desc = layer->desc; + struct regmap *regmap = layer->hlcdc->regmap; + + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR, + 0xffffffff); + regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR, + ATMEL_HLCDC_LAYER_RST); + + atmel_hlcdc_layer_dma_cleanup(dev, layer); + drm_flip_work_cleanup(&layer->gc); +} Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DRM_ATMEL_HLCDC_LAYER_H +#define DRM_ATMEL_HLCDC_LAYER_H + +#include <linux/mfd/atmel-hlcdc.h> + +#include <drm/drm_crtc.h> +#include <drm/drm_flip_work.h> +#include <drm/drmP.h> + +#define ATMEL_HLCDC_LAYER_CHER 0x0 +#define ATMEL_HLCDC_LAYER_CHDR 0x4 +#define ATMEL_HLCDC_LAYER_CHSR 0x8 +#define ATMEL_HLCDC_LAYER_DMA_CHAN BIT(0) +#define ATMEL_HLCDC_LAYER_UPDATE BIT(1) +#define ATMEL_HLCDC_LAYER_A2Q BIT(2) +#define ATMEL_HLCDC_LAYER_RST BIT(8) + +#define ATMEL_HLCDC_LAYER_IER 0xc +#define ATMEL_HLCDC_LAYER_IDR 0x10 +#define ATMEL_HLCDC_LAYER_IMR 0x14 +#define ATMEL_HLCDC_LAYER_ISR 0x18 +#define ATMEL_HLCDC_LAYER_DFETCH BIT(0) +#define ATMEL_HLCDC_LAYER_LFETCH BIT(1) +#define ATMEL_HLCDC_LAYER_DMA_IRQ BIT(2) +#define ATMEL_HLCDC_LAYER_DSCR_IRQ BIT(3) +#define ATMEL_HLCDC_LAYER_ADD_IRQ BIT(4) +#define ATMEL_HLCDC_LAYER_DONE_IRQ BIT(5) +#define ATMEL_HLCDC_LAYER_OVR_IRQ BIT(6) + +#define ATMEL_HLCDC_LAYER_PLANE_HEAD(n) (((n) * 0x10) + 0x1c) +#define ATMEL_HLCDC_LAYER_PLANE_ADDR(n) (((n) * 0x10) + 0x20) +#define ATMEL_HLCDC_LAYER_PLANE_CTRL(n) (((n) * 0x10) + 0x24) +#define ATMEL_HLCDC_LAYER_PLANE_NEXT(n) (((n) * 0x10) + 0x28) +#define ATMEL_HLCDC_LAYER_CFG(p, c) (((c) * 4) + ((p)->max_planes * 0x10) + 0x1c) + +#define ATMEL_HLCDC_LAYER_DMA_CFG_ID 0 +#define ATMEL_HLCDC_LAYER_DMA_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, ATMEL_HLCDC_LAYER_DMA_CFG_ID) +#define ATMEL_HLCDC_LAYER_DMA_SIF BIT(0) +#define ATMEL_HLCDC_LAYER_DMA_BLEN_MASK GENMASK(5, 4) +#define ATMEL_HLCDC_LAYER_DMA_BLEN_SINGLE (0 << 4) +#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR4 (1 << 4) +#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR8 (2 << 4) +#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 (3 << 4) +#define ATMEL_HLCDC_LAYER_DMA_DLBO BIT(8) +#define ATMEL_HLCDC_LAYER_DMA_ROTDIS BIT(12) +#define ATMEL_HLCDC_LAYER_DMA_LOCKDIS BIT(13) + +#define ATMEL_HLCDC_LAYER_FORMAT_CFG_ID 1 +#define ATMEL_HLCDC_LAYER_FORMAT_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, ATMEL_HLCDC_LAYER_FORMAT_CFG_ID) +#define ATMEL_HLCDC_LAYER_RGB (0 << 0) +#define ATMEL_HLCDC_LAYER_CLUT (1 << 0) +#define ATMEL_HLCDC_LAYER_YUV (2 << 0) +#define ATMEL_HLCDC_RGB_MODE(m) (((m) & 0xf) << 4) +#define ATMEL_HLCDC_CLUT_MODE(m) (((m) & 0x3) << 8) +#define ATMEL_HLCDC_YUV_MODE(m) (((m) & 0xf) << 12) +#define ATMEL_HLCDC_YUV422ROT BIT(16) +#define ATMEL_HLCDC_YUV422SWP BIT(17) +#define ATMEL_HLCDC_DSCALEOPT BIT(20) + +#define ATMEL_HLCDC_XRGB4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(0)) +#define ATMEL_HLCDC_ARGB4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(1)) +#define ATMEL_HLCDC_RGBA4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(2)) +#define ATMEL_HLCDC_RGB565_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(3)) +#define ATMEL_HLCDC_ARGB1555_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(4)) +#define ATMEL_HLCDC_XRGB8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(9)) +#define ATMEL_HLCDC_RGB888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(10)) +#define ATMEL_HLCDC_ARGB8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(12)) +#define ATMEL_HLCDC_RGBA8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(13)) + +#define ATMEL_HLCDC_AYUV_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(0)) +#define ATMEL_HLCDC_YUYV_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(1)) +#define ATMEL_HLCDC_UYVY_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(2)) +#define ATMEL_HLCDC_YVYU_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(3)) +#define ATMEL_HLCDC_VYUY_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(4)) +#define ATMEL_HLCDC_NV61_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(5)) +#define ATMEL_HLCDC_YUV422_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(6)) +#define ATMEL_HLCDC_NV21_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(7)) +#define ATMEL_HLCDC_YUV420_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(8)) + +#define ATMEL_HLCDC_LAYER_POS_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.pos) +#define ATMEL_HLCDC_LAYER_SIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.size) +#define ATMEL_HLCDC_LAYER_MEMSIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.memsize) +#define ATMEL_HLCDC_LAYER_XSTRIDE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.xstride) +#define ATMEL_HLCDC_LAYER_PSTRIDE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.pstride) +#define ATMEL_HLCDC_LAYER_DFLTCOLOR_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.default_color) +#define ATMEL_HLCDC_LAYER_CRKEY_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.chroma_key) +#define ATMEL_HLCDC_LAYER_CRKEY_MASK_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.chroma_key_mask) + +#define ATMEL_HLCDC_LAYER_GENERAL_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.general_config) +#define ATMEL_HLCDC_LAYER_CRKEY BIT(0) +#define ATMEL_HLCDC_LAYER_INV BIT(1) +#define ATMEL_HLCDC_LAYER_ITER2BL BIT(2) +#define ATMEL_HLCDC_LAYER_ITER BIT(3) +#define ATMEL_HLCDC_LAYER_REVALPHA BIT(4) +#define ATMEL_HLCDC_LAYER_GAEN BIT(5) +#define ATMEL_HLCDC_LAYER_LAEN BIT(6) +#define ATMEL_HLCDC_LAYER_OVR BIT(7) +#define ATMEL_HLCDC_LAYER_DMA BIT(8) +#define ATMEL_HLCDC_LAYER_REP BIT(9) +#define ATMEL_HLCDC_LAYER_DSTKEY BIT(10) +#define ATMEL_HLCDC_LAYER_DISCEN BIT(11) +#define ATMEL_HLCDC_LAYER_GA_SHIFT 16 +#define ATMEL_HLCDC_LAYER_GA_MASK GENMASK(23, ATMEL_HLCDC_LAYER_GA_SHIFT) + +#define ATMEL_HLCDC_LAYER_CSC_CFG(p, o) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.csc + o) + +#define ATMEL_HLCDC_LAYER_DISC_POS_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.disc_pos) + +#define ATMEL_HLCDC_LAYER_DISC_SIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.disc_size) + +#define ATMEL_HLCDC_MAX_PLANES 3 + +#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED BIT(0) +#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED BIT(1) +#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2) +#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3) + +/** + * Atmel HLCDC Layer registers layout structure + * + * Each HLCDC layer has its own register organization and a given register + * can be placed differently on 2 different layers depending on its + * capabilities. + * This structure stores common registers layout for a given layer and is + * used by HLCDC layer code to choose the appropriate register to write to + * or to read from. + * + * For all fields, a value of zero means "unsupported". + * + * See Atmel's datasheet for a detailled description of these registers. + * + * @xstride: xstride registers + * @pstride: pstride registers + * @pos: position register + * @size: displayed size register + * @memsize: memory size register + * @default_color: default color register + * @chroma_key: chroma key register + * @chroma_key_mask: chroma key mask register + * @general_config: general layer config register + * @disc_pos: discard area position register + * @disc_size: discard area size register + * @csc: color space conversion register + */ +struct atmel_hlcdc_layer_cfg_layout { + int xstride[ATMEL_HLCDC_MAX_PLANES]; + int pstride[ATMEL_HLCDC_MAX_PLANES]; + int pos; + int size; + int memsize; + int default_color; + int chroma_key; + int chroma_key_mask; + int general_config; + int disc_pos; + int disc_size; + int csc; +}; + +/** + * Atmel HLCDC framebuffer flip structure + * + * This structure is allocated when someone asked for a layer update (most + * likely a DRM plane update, either primary, overlay or cursor plane) and + * released when the layer do not need to reference the framebuffer object + * anymore (i.e. the layer was disabled or updated). + * + * @dscrs: DMA descriptors + * @fb: the referenced framebuffer object + * @ngems: number of GEM objects referenced by the fb element + * @status: fb flip operation status + */ +struct atmel_hlcdc_layer_fb_flip { + struct atmel_hlcdc_dma_channel_dscr *dscrs[ATMEL_HLCDC_MAX_PLANES]; + struct drm_flip_task *task; + struct drm_framebuffer *fb; + int ngems; + u32 status; +}; + +/** + * Atmel HLCDC DMA descriptor structure + * + * This structure is used by the HLCDC DMA engine to schedule a DMA transfer. + * + * The structure fields must remain in this specific order, because they're + * used by the HLCDC DMA engine, which expect them in this order. + * HLCDC DMA descriptors must be aligned on 64 bits. + * + * @addr: buffer DMA address + * @ctrl: DMA transfer options + * @next: next DMA descriptor to fetch + * @gem_flip: the attached gem_flip operation + */ +struct atmel_hlcdc_dma_channel_dscr { + dma_addr_t addr; + u32 ctrl; + dma_addr_t next; + u32 status; +} __aligned(sizeof(u64)); + +/** + * Atmel HLCDC layer types + */ +enum atmel_hlcdc_layer_type { + ATMEL_HLCDC_BASE_LAYER, + ATMEL_HLCDC_OVERLAY_LAYER, + ATMEL_HLCDC_CURSOR_LAYER, + ATMEL_HLCDC_PP_LAYER, +}; + +/** + * Atmel HLCDC Supported formats structure + * + * This structure list all the formats supported by a given layer. + * + * @nformats: number of supported formats + * @formats: supported formats + */ +struct atmel_hlcdc_formats { + int nformats; + uint32_t *formats; +}; + +/** + * Atmel HLCDC Layer description structure + * + * This structure describe the capabilities provided by a given layer. + * + * @name: layer name + * @type: layer type + * @id: layer id + * @regs_offset: offset of the layer registers from the HLCDC registers base + * @nconfigs: number of config registers provided by this layer + * @formats: supported formats + * @layout: config registers layout + * @max_width: maximum width supported by this layer (0 means unlimited) + * @max_height: maximum height supported by this layer (0 means unlimited) + */ +struct atmel_hlcdc_layer_desc { + const char *name; + enum atmel_hlcdc_layer_type type; + int id; + int regs_offset; + int nconfigs; + struct atmel_hlcdc_formats *formats; + struct atmel_hlcdc_layer_cfg_layout layout; + int max_width; + int max_height; +}; + +/** + * Atmel HLCDC Layer Update Slot structure + * + * This structure stores layer update requests to be applied on next frame. + * This is the base structure behind the atomic layer update infrastructure. + * + * Atomic layer update provides a way to update all layer's parameters + * simultaneously. This is needed to avoid incompatible sequential updates + * like this one: + * 1) update layer format from RGB888 (1 plane/buffer) to YUV422 + * (2 planes/buffers) + * 2) the format update is applied but the DMA channel for the second + * plane/buffer is not enabled + * 3) enable the DMA channel for the second plane + * + * @fb_flip: fb_flip object + * @updated_configs: bitmask used to record modified configs + * @configs: new config values + */ +struct atmel_hlcdc_layer_update_slot { + struct atmel_hlcdc_layer_fb_flip *fb_flip; + unsigned long *updated_configs; + u32 *configs; +}; + +/** + * Atmel HLCDC Layer Update structure + * + * This structure provides a way to queue layer update requests. + * + * At a given time there is at most: + * - one pending update request, which means the update request has been + * committed (or validated) and is waiting for the DMA channel(s) to be + * available + * - one request being prepared, which means someone started a layer update + * but has not committed it yet. There cannot be more than one started + * request, because the update lock is taken when starting a layer update + * and release when committing or rolling back the request. + * + * @slots: update slots. One is used for pending request and the other one + * for started update request + * @pending: the pending slot index or -1 if no request is pending + * @next: the started update slot index or -1 no update has been started + */ +struct atmel_hlcdc_layer_update { + struct atmel_hlcdc_layer_update_slot slots[2]; + int pending; + int next; +}; + +enum atmel_hlcdc_layer_dma_channel_status { + ATMEL_HLCDC_LAYER_DISABLED, + ATMEL_HLCDC_LAYER_ENABLED, + ATMEL_HLCDC_LAYER_DISABLING, +}; + +/** + * Atmel HLCDC Layer DMA channel structure + * + * This structure stores information on the DMA channel associated to a + * given layer. + * + * @status: DMA channel status + * @cur: current framebuffer + * @queue: next framebuffer + * @dscrs: allocated DMA descriptors + */ +struct atmel_hlcdc_layer_dma_channel { + enum atmel_hlcdc_layer_dma_channel_status status; + struct atmel_hlcdc_layer_fb_flip *cur; + struct atmel_hlcdc_layer_fb_flip *queue; + struct atmel_hlcdc_dma_channel_dscr *dscrs; +}; + +/** + * Atmel HLCDC Layer structure + * + * This structure stores information on the layer instance. + * + * @desc: layer description + * @max_planes: maximum planes/buffers that can be associated with this layer. + * This depends on the supported formats. + * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device + * @dma: dma channel + * @gc: fb flip garbage collector + * @update: update handler + * @lock: layer lock + */ +struct atmel_hlcdc_layer { + const struct atmel_hlcdc_layer_desc *desc; + int max_planes; + struct atmel_hlcdc *hlcdc; + struct workqueue_struct *wq; + struct drm_flip_work gc; + struct atmel_hlcdc_layer_dma_channel dma; + struct atmel_hlcdc_layer_update update; + spinlock_t lock; +}; + +void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer); + +int atmel_hlcdc_layer_init(struct drm_device *dev, + struct atmel_hlcdc_layer *layer, + const struct atmel_hlcdc_layer_desc *desc); + +void atmel_hlcdc_layer_cleanup(struct drm_device *dev, + struct atmel_hlcdc_layer *layer); + +int atmel_hlcdc_layer_disable(struct atmel_hlcdc_layer *layer); + +int atmel_hlcdc_layer_update_start(struct atmel_hlcdc_layer *layer); + +void atmel_hlcdc_layer_update_cfg(struct atmel_hlcdc_layer *layer, int cfg, + u32 mask, u32 val); + +void atmel_hlcdc_layer_update_set_fb(struct atmel_hlcdc_layer *layer, + struct drm_framebuffer *fb, + unsigned int *offsets); + +void atmel_hlcdc_layer_update_set_finished(struct atmel_hlcdc_layer *layer, + void (*finished)(void *data), + void *finished_data); + +void atmel_hlcdc_layer_update_rollback(struct atmel_hlcdc_layer *layer); + +void atmel_hlcdc_layer_update_commit(struct atmel_hlcdc_layer *layer); + +#endif /* DRM_ATMEL_HLCDC_LAYER_H */ Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Traphandler + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com> + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/component.h> +#include <linux/of_graph.h> + +#include <drm/drmP.h> +#include <drm/drm_panel.h> + +#include "atmel_hlcdc_dc.h" + +/** + * Atmel HLCDC RGB output mode + */ +enum atmel_hlcdc_connector_rgb_mode { + ATMEL_HLCDC_CONNECTOR_RGB444, + ATMEL_HLCDC_CONNECTOR_RGB565, + ATMEL_HLCDC_CONNECTOR_RGB666, + ATMEL_HLCDC_CONNECTOR_RGB888, +}; + +/** + * Atmel HLCDC Panel device structure + * + * This structure is specialization of the slave device structure to + * interface with drm panels. + * + * @connector: DRM connector + * @encoder: DRM encoder + * @dpms: current DPMS mode + * @panel: drm panel attached to this slave device + */ +struct atmel_hlcdc_panel { + struct drm_connector connector; + struct drm_encoder encoder; + int dpms; + struct drm_panel *panel; +}; + +static inline struct atmel_hlcdc_panel * +drm_connector_to_atmel_hlcdc_panel(struct drm_connector *connector) +{ + return container_of(connector, struct atmel_hlcdc_panel, + connector); +} + +static inline struct atmel_hlcdc_panel * +drm_encoder_to_atmel_hlcdc_panel(struct drm_encoder *encoder) +{ + return container_of(encoder, struct atmel_hlcdc_panel, encoder); +} + +static void atmel_hlcdc_panel_encoder_dpms(struct drm_encoder *encoder, + int mode) +{ + struct atmel_hlcdc_panel *panel = + drm_encoder_to_atmel_hlcdc_panel(encoder); + + if (mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; + + if (mode == panel->dpms) + return; + + if (mode != DRM_MODE_DPMS_ON) + drm_panel_disable(panel->panel); + else + drm_panel_enable(panel->panel); + + panel->dpms = mode; +} + +static bool +atmel_hlcdc_panel_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted) +{ + return true; +} + +static void atmel_hlcdc_panel_encoder_prepare(struct drm_encoder *encoder) +{ + atmel_hlcdc_panel_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); +} + +static void atmel_hlcdc_panel_encoder_commit(struct drm_encoder *encoder) +{ + atmel_hlcdc_panel_encoder_dpms(encoder, DRM_MODE_DPMS_ON); +} + +static void +atmel_hlcdc_panel_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted) +{ + +} + +static struct drm_encoder_helper_funcs atmel_hlcdc_panel_encoder_helper_funcs = { + .dpms = atmel_hlcdc_panel_encoder_dpms, + .mode_fixup = atmel_hlcdc_panel_encoder_mode_fixup, + .prepare = atmel_hlcdc_panel_encoder_prepare, + .commit = atmel_hlcdc_panel_encoder_commit, + .mode_set = atmel_hlcdc_panel_encoder_mode_set, +}; + +static void atmel_hlcdc_panel_encoder_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); + memset(encoder, 0, sizeof(*encoder)); +} + +static const struct drm_encoder_funcs atmel_hlcdc_panel_encoder_funcs = { + .destroy = atmel_hlcdc_panel_encoder_destroy, +}; + +static int atmel_hlcdc_panel_get_modes(struct drm_connector *connector) +{ + struct atmel_hlcdc_panel *panel = + drm_connector_to_atmel_hlcdc_panel(connector); + + return panel->panel->funcs->get_modes(panel->panel); +} + +static struct drm_encoder * +atmel_hlcdc_panel_best_encoder(struct drm_connector *connector) +{ + struct atmel_hlcdc_panel *panel = + drm_connector_to_atmel_hlcdc_panel(connector); + + return &panel->encoder; +} + +static struct drm_connector_helper_funcs atmel_hlcdc_panel_connector_helper_funcs = { + .get_modes = atmel_hlcdc_panel_get_modes, + .best_encoder = atmel_hlcdc_panel_best_encoder, +}; + +static enum drm_connector_status +atmel_hlcdc_panel_connector_detect(struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +static void +atmel_hlcdc_panel_connector_destroy(struct drm_connector *connector) +{ + struct atmel_hlcdc_panel *panel = + drm_connector_to_atmel_hlcdc_panel(connector); + + drm_panel_detach(panel->panel); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_funcs atmel_hlcdc_panel_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .detect = atmel_hlcdc_panel_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = atmel_hlcdc_panel_connector_destroy, +}; + +static int atmel_hlcdc_create_panel_output(struct drm_device *dev, + struct of_endpoint *ep) +{ + struct device_node *np; + struct drm_panel *p = NULL; + struct atmel_hlcdc_panel *panel; + int ret; + + np = of_graph_get_remote_port_parent(ep->local_node); + if (!np) + return -EINVAL; + + p = of_drm_find_panel(np); + of_node_put(np); + + if (!p) + return -EPROBE_DEFER; + + panel = devm_kzalloc(dev->dev, sizeof(*panel), GFP_KERNEL); + if (!panel) + return -EINVAL; + + panel->dpms = DRM_MODE_DPMS_OFF; + + drm_encoder_helper_add(&panel->encoder, + &atmel_hlcdc_panel_encoder_helper_funcs); + ret = drm_encoder_init(dev, &panel->encoder, + &atmel_hlcdc_panel_encoder_funcs, + DRM_MODE_ENCODER_LVDS); + if (ret) + return ret; + + panel->connector.dpms = DRM_MODE_DPMS_OFF; + panel->connector.polled = DRM_CONNECTOR_POLL_CONNECT; + drm_connector_helper_add(&panel->connector, + &atmel_hlcdc_panel_connector_helper_funcs); + ret = drm_connector_init(dev, &panel->connector, + &atmel_hlcdc_panel_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + if (ret) + goto err_encoder_cleanup; + + drm_mode_connector_attach_encoder(&panel->connector, + &panel->encoder); + panel->encoder.possible_crtcs = 0x1; + + drm_panel_attach(p, &panel->connector); + panel->panel = p; + + return 0; + +err_encoder_cleanup: + drm_encoder_cleanup(&panel->encoder); + + return ret; +} + +int atmel_hlcdc_output_set_rgb_mode(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + struct drm_connector *connector; + unsigned int valid_modes = BIT(ATMEL_HLCDC_CONNECTOR_RGB444) | + BIT(ATMEL_HLCDC_CONNECTOR_RGB565) | + BIT(ATMEL_HLCDC_CONNECTOR_RGB666) | + BIT(ATMEL_HLCDC_CONNECTOR_RGB888); + u32 cfg; + + /* Prepare the encoders and CRTCs before setting the mode. */ + list_for_each_entry(connector, &dev->mode_config.connector_list, + head) { + struct drm_display_info *info = &connector->display_info; + unsigned int mask = 0; + int i; + + for (i = 0; i < info->num_bus_formats; i++) { + switch (info->bus_formats[i]) { + case MEDIA_BUS_FMT_RGB444_1X12: + mask |= BIT(ATMEL_HLCDC_CONNECTOR_RGB444); + break; + case MEDIA_BUS_FMT_RGB565_1X16: + mask |= BIT(ATMEL_HLCDC_CONNECTOR_RGB565); + break; + case MEDIA_BUS_FMT_RGB666_1X18: + mask |= BIT(ATMEL_HLCDC_CONNECTOR_RGB666); + break; + case MEDIA_BUS_FMT_RGB888_1X24: + mask |= BIT(ATMEL_HLCDC_CONNECTOR_RGB888); + break; + default: + break; + } + } + + valid_modes &= mask; + } + + if (!valid_modes) + return -EINVAL; + + /* TODO: choose best mode according to input format ? */ + cfg = (fls(valid_modes) - 1) << 8; + + regmap_update_bits(dc->hlcdc->regmap, ATMEL_HLCDC_CFG(5), + ATMEL_HLCDC_MODE_MASK, cfg); + + return 0; +} + +static int atmel_hlcdc_create_panels(struct drm_device *dev) +{ + struct device_node *np = NULL, *remote = NULL; + struct of_endpoint ep; + int ret = 0; + + for (np = of_graph_get_next_endpoint(dev->dev->of_node, np); + np; + np = of_graph_get_next_endpoint(dev->dev->of_node, np)) { + + ret = of_graph_parse_endpoint(np, &ep); + if (ret) + break; + + remote = of_graph_get_remote_port_parent(ep.local_node); + if (!remote) { + ret = -EINVAL; + break; + } + + if (of_device_is_compatible(remote, "simple-panel") && + of_device_is_available(remote)) { + ret = atmel_hlcdc_create_panel_output(dev, &ep); + if (ret) + break; + } + + of_node_put(remote); + } + + of_node_put(np); + + return ret; +} + +static void atmel_hlcdc_destroy_panels(struct drm_device *dev) +{ + +} + +static int compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +bool atmel_hlcdc_output_panels_ready(struct device *dev) +{ + struct device_node *np = NULL, *remote = NULL; + struct of_endpoint ep; + bool ready = true; + int ret = 0; + + for (np = of_graph_get_next_endpoint(dev->of_node, np); + np && ready; + np = of_graph_get_next_endpoint(dev->of_node, np)) { + + ret = of_graph_parse_endpoint(np, &ep); + if (ret) + break; + + remote = of_graph_get_remote_port_parent(ep.local_node); + if (!remote) { + ret = -EINVAL; + break; + } + + if (of_device_is_compatible(remote, "simple-panel") && + of_device_is_available(remote)) { + if (!of_drm_find_panel(remote)) + ready = false; + } + + of_node_put(remote); + } + + of_node_put(np); + + return ready; +} + +int atmel_hlcdc_find_output_components(struct device *dev, + struct component_match **match) +{ + struct device_node *np = NULL, *remote = NULL; + struct of_endpoint ep; + int ret; + + for (np = of_graph_get_next_endpoint(dev->of_node, np); + np; + np = of_graph_get_next_endpoint(dev->of_node, np)) { + + ret = of_graph_parse_endpoint(np, &ep); + if (ret) + break; + + remote = of_graph_get_remote_port_parent(ep.local_node); + if (!remote) { + ret = -EINVAL; + break; + } + + if (!of_device_is_compatible(remote, "simple-panel")) + component_match_add(dev, match, compare_of, + remote); + } + + of_node_put(np); + + return ret; +} + +int atmel_hlcdc_create_outputs(struct drm_device *ddev) +{ + return atmel_hlcdc_create_panels(ddev); +} + +void atmel_hlcdc_destroy_outputs(struct drm_device *ddev) +{ + atmel_hlcdc_destroy_panels(ddev); +} + + Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include "atmel_hlcdc_dc.h" + +#define SUBPIXEL_MASK 0xffff + +static uint32_t rgb_formats[] = { + DRM_FORMAT_XRGB4444, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGBA8888, +}; + +struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = { + .formats = rgb_formats, + .nformats = ARRAY_SIZE(rgb_formats), +}; + +static uint32_t rgb_and_yuv_formats[] = { + DRM_FORMAT_XRGB4444, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_AYUV, + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, + DRM_FORMAT_YVYU, + DRM_FORMAT_VYUY, + DRM_FORMAT_NV21, + DRM_FORMAT_NV61, + DRM_FORMAT_YUV422, + DRM_FORMAT_YUV420, +}; + +struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = { + .formats = rgb_and_yuv_formats, + .nformats = ARRAY_SIZE(rgb_and_yuv_formats), +}; + +static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode) +{ + switch (format) { + case DRM_FORMAT_XRGB4444: + *mode = ATMEL_HLCDC_XRGB4444_MODE; + break; + case DRM_FORMAT_ARGB4444: + *mode = ATMEL_HLCDC_ARGB4444_MODE; + break; + case DRM_FORMAT_RGBA4444: + *mode = ATMEL_HLCDC_RGBA4444_MODE; + break; + case DRM_FORMAT_RGB565: + *mode = ATMEL_HLCDC_RGB565_MODE; + break; + case DRM_FORMAT_RGB888: + *mode = ATMEL_HLCDC_RGB888_MODE; + break; + case DRM_FORMAT_ARGB1555: + *mode = ATMEL_HLCDC_ARGB1555_MODE; + break; + case DRM_FORMAT_XRGB8888: + *mode = ATMEL_HLCDC_XRGB8888_MODE; + break; + case DRM_FORMAT_ARGB8888: + *mode = ATMEL_HLCDC_ARGB8888_MODE; + break; + case DRM_FORMAT_RGBA8888: + *mode = ATMEL_HLCDC_RGBA8888_MODE; + break; + case DRM_FORMAT_AYUV: + *mode = ATMEL_HLCDC_AYUV_MODE; + break; + case DRM_FORMAT_YUYV: + *mode = ATMEL_HLCDC_YUYV_MODE; + break; + case DRM_FORMAT_UYVY: + *mode = ATMEL_HLCDC_UYVY_MODE; + break; + case DRM_FORMAT_YVYU: + *mode = ATMEL_HLCDC_YVYU_MODE; + break; + case DRM_FORMAT_VYUY: + *mode = ATMEL_HLCDC_VYUY_MODE; + break; + case DRM_FORMAT_NV21: + *mode = ATMEL_HLCDC_NV21_MODE; + break; + case DRM_FORMAT_NV61: + *mode = ATMEL_HLCDC_NV61_MODE; + break; + case DRM_FORMAT_YUV420: + *mode = ATMEL_HLCDC_YUV420_MODE; + break; + case DRM_FORMAT_YUV422: + *mode = ATMEL_HLCDC_YUV422_MODE; + break; + default: + return -ENOTSUPP; + } + + return 0; +} + +static bool atmel_hlcdc_format_embedds_alpha(u32 format) +{ + int i; + + for (i = 0; i < sizeof(format); i++) { + char tmp = (format >> (8 * i)) & 0xff; + + if (tmp == 'A') + return true; + } + + return false; +} + +static u32 heo_downscaling_xcoef[] = { + 0x11343311, + 0x000000f7, + 0x1635300c, + 0x000000f9, + 0x1b362c08, + 0x000000fb, + 0x1f372804, + 0x000000fe, + 0x24382400, + 0x00000000, + 0x28371ffe, + 0x00000004, + 0x2c361bfb, + 0x00000008, + 0x303516f9, + 0x0000000c, +}; + +static u32 heo_downscaling_ycoef[] = { + 0x00123737, + 0x00173732, + 0x001b382d, + 0x001f3928, + 0x00243824, + 0x0028391f, + 0x002d381b, + 0x00323717, +}; + +static u32 heo_upscaling_xcoef[] = { + 0xf74949f7, + 0x00000000, + 0xf55f33fb, + 0x000000fe, + 0xf5701efe, + 0x000000ff, + 0xf87c0dff, + 0x00000000, + 0x00800000, + 0x00000000, + 0x0d7cf800, + 0x000000ff, + 0x1e70f5ff, + 0x000000fe, + 0x335ff5fe, + 0x000000fb, +}; + +static u32 heo_upscaling_ycoef[] = { + 0x00004040, + 0x00075920, + 0x00056f0c, + 0x00027b03, + 0x00008000, + 0x00037b02, + 0x000c6f05, + 0x00205907, +}; + +static void +atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_update_req *req) +{ + const struct atmel_hlcdc_layer_cfg_layout *layout = + &plane->layer.desc->layout; + + if (layout->size) + atmel_hlcdc_layer_update_cfg(&plane->layer, + layout->size, + 0xffffffff, + (req->crtc_w - 1) | + ((req->crtc_h - 1) << 16)); + + if (layout->memsize) + atmel_hlcdc_layer_update_cfg(&plane->layer, + layout->memsize, + 0xffffffff, + (req->src_w - 1) | + ((req->src_h - 1) << 16)); + + if (layout->pos) + atmel_hlcdc_layer_update_cfg(&plane->layer, + layout->pos, + 0xffffffff, + req->crtc_x | + (req->crtc_y << 16)); + + /* TODO: rework the rescaling part */ + if (req->crtc_w != req->src_w || req->crtc_h != req->src_h) { + u32 factor_reg = 0; + + if (req->crtc_w != req->src_w) { + int i; + u32 factor; + u32 *coeff_tab = heo_upscaling_xcoef; + u32 max_memsize; + + if (req->crtc_w < req->src_w) + coeff_tab = heo_downscaling_xcoef; + for (i = 0; i < ARRAY_SIZE(heo_upscaling_xcoef); i++) + atmel_hlcdc_layer_update_cfg(&plane->layer, + 17 + i, + 0xffffffff, + coeff_tab[i]); + factor = ((8 * 256 * req->src_w) - (256 * 4)) / + req->crtc_w; + factor++; + max_memsize = ((factor * req->crtc_w) + (256 * 4)) / + 2048; + if (max_memsize > req->src_w) + factor--; + factor_reg |= factor | 0x80000000; + } + + if (req->crtc_h != req->src_h) { + int i; + u32 factor; + u32 *coeff_tab = heo_upscaling_ycoef; + u32 max_memsize; + + if (req->crtc_w < req->src_w) + coeff_tab = heo_downscaling_ycoef; + for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++) + atmel_hlcdc_layer_update_cfg(&plane->layer, + 33 + i, + 0xffffffff, + coeff_tab[i]); + factor = ((8 * 256 * req->src_w) - (256 * 4)) / + req->crtc_w; + factor++; + max_memsize = ((factor * req->crtc_w) + (256 * 4)) / + 2048; + if (max_memsize > req->src_w) + factor--; + factor_reg |= (factor << 16) | 0x80000000; + } + + atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, + factor_reg); + } +} + +static void +atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_update_req *req) +{ + const struct atmel_hlcdc_layer_cfg_layout *layout = + &plane->layer.desc->layout; + unsigned int cfg = ATMEL_HLCDC_LAYER_DMA; + + if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) { + cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL | + ATMEL_HLCDC_LAYER_ITER; + + if (atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format)) + cfg |= ATMEL_HLCDC_LAYER_LAEN; + else + cfg |= ATMEL_HLCDC_LAYER_GAEN; + } + + atmel_hlcdc_layer_update_cfg(&plane->layer, + ATMEL_HLCDC_LAYER_DMA_CFG_ID, + ATMEL_HLCDC_LAYER_DMA_BLEN_MASK, + ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16); + + atmel_hlcdc_layer_update_cfg(&plane->layer, layout->general_config, + ATMEL_HLCDC_LAYER_ITER2BL | + ATMEL_HLCDC_LAYER_ITER | + ATMEL_HLCDC_LAYER_GAEN | + ATMEL_HLCDC_LAYER_LAEN | + ATMEL_HLCDC_LAYER_OVR | + ATMEL_HLCDC_LAYER_DMA, cfg); +} + +static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_update_req *req) +{ + u32 cfg; + int ret; + + ret = atmel_hlcdc_format_to_plane_mode(req->fb->pixel_format, &cfg); + if (ret) + return; + + if ((req->fb->pixel_format == DRM_FORMAT_YUV422 || + req->fb->pixel_format == DRM_FORMAT_NV61) && + (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270)))) + cfg |= ATMEL_HLCDC_YUV422ROT; + + atmel_hlcdc_layer_update_cfg(&plane->layer, + ATMEL_HLCDC_LAYER_FORMAT_CFG_ID, + 0xffffffff, + cfg); + + /* + * Rotation optimization is not working on RGB888 (rotation is still + * working but without any optimization). + */ + if (req->fb->pixel_format == DRM_FORMAT_RGB888) + cfg = ATMEL_HLCDC_LAYER_DMA_ROTDIS; + else + cfg = 0; + + atmel_hlcdc_layer_update_cfg(&plane->layer, + ATMEL_HLCDC_LAYER_DMA_CFG_ID, + ATMEL_HLCDC_LAYER_DMA_ROTDIS, cfg); +} + +static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_update_req *req) +{ + struct atmel_hlcdc_layer *layer = &plane->layer; + const struct atmel_hlcdc_layer_cfg_layout *layout = + &layer->desc->layout; + int i; + + atmel_hlcdc_layer_update_set_fb(&plane->layer, req->fb, req->offsets); + + for (i = 0; i < req->nplanes; i++) { + if (layout->xstride[i]) { + atmel_hlcdc_layer_update_cfg(&plane->layer, + layout->xstride[i], + 0xffffffff, + req->xstride[i]); + } + + if (layout->pstride[i]) { + atmel_hlcdc_layer_update_cfg(&plane->layer, + layout->pstride[i], + 0xffffffff, + req->pstride[i]); + } + } +} + +static int atmel_hlcdc_plane_check_update_req(struct drm_plane *p, + struct atmel_hlcdc_plane_update_req *req, + const struct drm_display_mode *mode) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + const struct atmel_hlcdc_layer_cfg_layout *layout = + &plane->layer.desc->layout; + + if (!layout->size && + (mode->hdisplay != req->crtc_w || + mode->vdisplay != req->crtc_h)) + return -EINVAL; + + if (plane->layer.desc->max_height && + req->crtc_h > plane->layer.desc->max_height) + return -EINVAL; + + if (plane->layer.desc->max_width && + req->crtc_w > plane->layer.desc->max_width) + return -EINVAL; + + if ((req->crtc_h != req->src_h || req->crtc_w != req->src_w) && + (!layout->memsize || + atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format))) + return -EINVAL; + + if (req->crtc_x < 0 || req->crtc_y < 0) + return -EINVAL; + + if (req->crtc_w + req->crtc_x > mode->hdisplay || + req->crtc_h + req->crtc_y > mode->vdisplay) + return -EINVAL; + + return 0; +} + +int atmel_hlcdc_plane_prepare_update_req(struct drm_plane *p, + struct atmel_hlcdc_plane_update_req *req, + const struct drm_display_mode *mode) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + unsigned int patched_crtc_w; + unsigned int patched_crtc_h; + unsigned int patched_src_w; + unsigned int patched_src_h; + unsigned int tmp; + int x_offset = 0; + int y_offset = 0; + int hsub = 1; + int vsub = 1; + int i; + + if ((req->src_x | req->src_y | req->src_w | req->src_h) & + SUBPIXEL_MASK) + return -EINVAL; + + req->src_x >>= 16; + req->src_y >>= 16; + req->src_w >>= 16; + req->src_h >>= 16; + + req->nplanes = drm_format_num_planes(req->fb->pixel_format); + if (req->nplanes > ATMEL_HLCDC_MAX_PLANES) + return -EINVAL; + + /* + * Swap width and size in case of 90 or 270 degrees rotation + */ + if (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) { + tmp = req->crtc_w; + req->crtc_w = req->crtc_h; + req->crtc_h = tmp; + tmp = req->src_w; + req->src_w = req->src_h; + req->src_h = tmp; + } + + if (req->crtc_x + req->crtc_w > mode->hdisplay) + patched_crtc_w = mode->hdisplay - req->crtc_x; + else + patched_crtc_w = req->crtc_w; + + if (req->crtc_x < 0) { + patched_crtc_w += req->crtc_x; + x_offset = -req->crtc_x; + req->crtc_x = 0; + } + + if (req->crtc_y + req->crtc_h > mode->vdisplay) + patched_crtc_h = mode->vdisplay - req->crtc_y; + else + patched_crtc_h = req->crtc_h; + + if (req->crtc_y < 0) { + patched_crtc_h += req->crtc_y; + y_offset = -req->crtc_y; + req->crtc_y = 0; + } + + patched_src_w = DIV_ROUND_CLOSEST(patched_crtc_w * req->src_w, + req->crtc_w); + patched_src_h = DIV_ROUND_CLOSEST(patched_crtc_h * req->src_h, + req->crtc_h); + + hsub = drm_format_horz_chroma_subsampling(req->fb->pixel_format); + vsub = drm_format_vert_chroma_subsampling(req->fb->pixel_format); + + for (i = 0; i < req->nplanes; i++) { + unsigned int offset = 0; + int xdiv = i ? hsub : 1; + int ydiv = i ? vsub : 1; + + req->bpp[i] = drm_format_plane_cpp(req->fb->pixel_format, i); + if (!req->bpp[i]) + return -EINVAL; + + switch (plane->rotation & 0xf) { + case BIT(DRM_ROTATE_90): + offset = ((y_offset + req->src_y + patched_src_w - 1) / + ydiv) * req->fb->pitches[i]; + offset += ((x_offset + req->src_x) / xdiv) * + req->bpp[i]; + req->xstride[i] = ((patched_src_w - 1) / ydiv) * + req->fb->pitches[i]; + req->pstride[i] = -req->fb->pitches[i] - req->bpp[i]; + break; + case BIT(DRM_ROTATE_180): + offset = ((y_offset + req->src_y + patched_src_h - 1) / + ydiv) * req->fb->pitches[i]; + offset += ((x_offset + req->src_x + patched_src_w - 1) / + xdiv) * req->bpp[i]; + req->xstride[i] = ((((patched_src_w - 1) / xdiv) - 1) * + req->bpp[i]) - req->fb->pitches[i]; + req->pstride[i] = -2 * req->bpp[i]; + break; + case BIT(DRM_ROTATE_270): + offset = ((y_offset + req->src_y) / ydiv) * + req->fb->pitches[i]; + offset += ((x_offset + req->src_x + patched_src_h - 1) / + xdiv) * req->bpp[i]; + req->xstride[i] = -(((patched_src_w - 1) / ydiv) * + req->fb->pitches[i]) - + (2 * req->bpp[i]); + req->pstride[i] = req->fb->pitches[i] - req->bpp[i]; + break; + case BIT(DRM_ROTATE_0): + default: + offset = ((y_offset + req->src_y) / ydiv) * + req->fb->pitches[i]; + offset += ((x_offset + req->src_x) / xdiv) * + req->bpp[i]; + req->xstride[i] = req->fb->pitches[i] - + ((patched_src_w / xdiv) * + req->bpp[i]); + req->pstride[i] = 0; + break; + } + + req->offsets[i] = offset + req->fb->offsets[i]; + } + + req->src_w = patched_src_w; + req->src_h = patched_src_h; + req->crtc_w = patched_crtc_w; + req->crtc_h = patched_crtc_h; + + return atmel_hlcdc_plane_check_update_req(p, req, mode); +} + +int atmel_hlcdc_plane_apply_update_req(struct drm_plane *p, + struct atmel_hlcdc_plane_update_req *req) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + int ret; + + ret = atmel_hlcdc_layer_update_start(&plane->layer); + if (ret) + return ret; + + atmel_hlcdc_plane_update_pos_and_size(plane, req); + atmel_hlcdc_plane_update_general_settings(plane, req); + atmel_hlcdc_plane_update_format(plane, req); + atmel_hlcdc_plane_update_buffers(plane, req); + + atmel_hlcdc_layer_update_commit(&plane->layer); + + return 0; +} + +int atmel_hlcdc_plane_update_with_mode(struct drm_plane *p, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, + unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + const struct drm_display_mode *mode) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + struct atmel_hlcdc_plane_update_req req; + int ret = 0; + + memset(&req, 0, sizeof(req)); + req.crtc_x = crtc_x; + req.crtc_y = crtc_y; + req.crtc_w = crtc_w; + req.crtc_h = crtc_h; + req.src_x = src_x; + req.src_y = src_y; + req.src_w = src_w; + req.src_h = src_h; + req.fb = fb; + + ret = atmel_hlcdc_plane_prepare_update_req(&plane->base, &req, mode); + if (ret) + return ret; + + if (!req.crtc_h || !req.crtc_w) + return atmel_hlcdc_layer_disable(&plane->layer); + + return atmel_hlcdc_plane_apply_update_req(&plane->base, &req); +} + +static int atmel_hlcdc_plane_update(struct drm_plane *p, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + return atmel_hlcdc_plane_update_with_mode(p, crtc, fb, crtc_x, crtc_y, + crtc_w, crtc_h, src_x, src_y, + src_w, src_h, &crtc->hwmode); +} + +static int atmel_hlcdc_plane_disable(struct drm_plane *p) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + + return atmel_hlcdc_layer_disable(&plane->layer); +} + +static void atmel_hlcdc_plane_destroy(struct drm_plane *p) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + + if (plane->base.fb) + drm_framebuffer_unreference(plane->base.fb); + + atmel_hlcdc_layer_cleanup(p->dev, &plane->layer); + + drm_plane_cleanup(p); + devm_kfree(p->dev->dev, plane); +} + +static int atmel_hlcdc_plane_set_alpha(struct atmel_hlcdc_plane *plane, + u8 alpha) +{ + atmel_hlcdc_layer_update_start(&plane->layer); + atmel_hlcdc_layer_update_cfg(&plane->layer, + plane->layer.desc->layout.general_config, + ATMEL_HLCDC_LAYER_GA_MASK, + alpha << ATMEL_HLCDC_LAYER_GA_SHIFT); + atmel_hlcdc_layer_update_commit(&plane->layer); + + return 0; +} + +static int atmel_hlcdc_plane_set_rotation(struct atmel_hlcdc_plane *plane, + unsigned int rotation) +{ + plane->rotation = rotation; + + return 0; +} + +static int atmel_hlcdc_plane_set_property(struct drm_plane *p, + struct drm_property *property, + uint64_t value) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + struct atmel_hlcdc_plane_properties *props = plane->properties; + + if (property == props->alpha) + atmel_hlcdc_plane_set_alpha(plane, value); + else if (property == props->rotation) + atmel_hlcdc_plane_set_rotation(plane, value); + else + return -EINVAL; + + return 0; +} + +static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc, + struct atmel_hlcdc_plane_properties *props) +{ + struct regmap *regmap = plane->layer.hlcdc->regmap; + + if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER || + desc->type == ATMEL_HLCDC_CURSOR_LAYER) { + drm_object_attach_property(&plane->base.base, + props->alpha, 255); + + /* Set default alpha value */ + regmap_update_bits(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_GENERAL_CFG(&plane->layer), + ATMEL_HLCDC_LAYER_GA_MASK, + ATMEL_HLCDC_LAYER_GA_MASK); + } + + if (desc->layout.xstride && desc->layout.pstride) + drm_object_attach_property(&plane->base.base, + props->rotation, + BIT(DRM_ROTATE_0)); + + if (desc->layout.csc) { + /* + * TODO: decare a "yuv-to-rgb-conv-factors" property to let + * userspace modify these factors (using a BLOB property ?). + */ + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 0), + 0x4c900091); + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 1), + 0x7a5f5090); + regmap_write(regmap, + desc->regs_offset + + ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 2), + 0x40040890); + } +} + +static struct drm_plane_funcs layer_plane_funcs = { + .update_plane = atmel_hlcdc_plane_update, + .disable_plane = atmel_hlcdc_plane_disable, + .set_property = atmel_hlcdc_plane_set_property, + .destroy = atmel_hlcdc_plane_destroy, +}; + +static struct atmel_hlcdc_plane * +atmel_hlcdc_plane_create(struct drm_device *dev, + const struct atmel_hlcdc_layer_desc *desc, + struct atmel_hlcdc_plane_properties *props) +{ + struct atmel_hlcdc_plane *plane; + enum drm_plane_type type; + int ret; + + plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL); + if (!plane) + return ERR_PTR(-ENOMEM); + + ret = atmel_hlcdc_layer_init(dev, &plane->layer, desc); + if (ret) + return ERR_PTR(ret); + + if (desc->type == ATMEL_HLCDC_BASE_LAYER) + type = DRM_PLANE_TYPE_PRIMARY; + else if (desc->type == ATMEL_HLCDC_CURSOR_LAYER) + type = DRM_PLANE_TYPE_CURSOR; + else + type = DRM_PLANE_TYPE_OVERLAY; + + ret = drm_universal_plane_init(dev, &plane->base, 0, + &layer_plane_funcs, + desc->formats->formats, + desc->formats->nformats, type); + if (ret) + return ERR_PTR(ret); + + /* Set default property values*/ + atmel_hlcdc_plane_init_properties(plane, desc, props); + + return plane; +} + +static struct atmel_hlcdc_plane_properties * +atmel_hlcdc_plane_create_properties(struct drm_device *dev) +{ + struct atmel_hlcdc_plane_properties *props; + + props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL); + if (!props) + return ERR_PTR(-ENOMEM); + + props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255); + if (!props->alpha) + return ERR_PTR(-ENOMEM); + + props->rotation = drm_mode_create_rotation_property(dev, + BIT(DRM_ROTATE_0) | + BIT(DRM_ROTATE_90) | + BIT(DRM_ROTATE_180) | + BIT(DRM_ROTATE_270)); + if (!props->rotation) + return ERR_PTR(-ENOMEM); + + return props; +} + +struct atmel_hlcdc_planes * +atmel_hlcdc_create_planes(struct drm_device *dev) +{ + struct atmel_hlcdc_dc *dc = dev->dev_private; + struct atmel_hlcdc_plane_properties *props; + struct atmel_hlcdc_planes *planes; + const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers; + int nlayers = dc->desc->nlayers; + int i; + + planes = devm_kzalloc(dev->dev, sizeof(*planes), GFP_KERNEL); + if (!planes) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < nlayers; i++) { + if (descs[i].type == ATMEL_HLCDC_OVERLAY_LAYER) + planes->noverlays++; + } + + if (planes->noverlays) { + planes->overlays = devm_kzalloc(dev->dev, + planes->noverlays * + sizeof(*planes->overlays), + GFP_KERNEL); + if (!planes->overlays) + return ERR_PTR(-ENOMEM); + } + + props = atmel_hlcdc_plane_create_properties(dev); + if (IS_ERR(props)) + return ERR_CAST(props); + + planes->noverlays = 0; + for (i = 0; i < nlayers; i++) { + struct atmel_hlcdc_plane *plane; + + if (descs[i].type == ATMEL_HLCDC_PP_LAYER) + continue; + + plane = atmel_hlcdc_plane_create(dev, &descs[i], props); + if (IS_ERR(plane)) + return ERR_CAST(plane); + + plane->properties = props; + + switch (descs[i].type) { + case ATMEL_HLCDC_BASE_LAYER: + if (planes->primary) + return ERR_PTR(-EINVAL); + planes->primary = plane; + break; + + case ATMEL_HLCDC_OVERLAY_LAYER: + planes->overlays[planes->noverlays++] = plane; + break; + + case ATMEL_HLCDC_CURSOR_LAYER: + if (planes->cursor) + return ERR_PTR(-EINVAL); + planes->cursor = plane; + break; + + default: + break; + } + } + + return planes; +} Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/Kconfig =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +config DRM_ATMEL_HLCDC + tristate "DRM Support for ATMEL HLCDC Display Controller" + depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC + select DRM_GEM_CMA_HELPER + select DRM_KMS_HELPER + select DRM_KMS_FB_HELPER + select DRM_KMS_CMA_HELPER + select DRM_PANEL + help + Choose this option if you have an ATMEL SoC with an HLCDC display + controller (i.e. at91sam9n12, at91sam9x5 family or sama5d3 family). Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/Makefile =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/atmel-hlcdc/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +atmel-hlcdc-dc-y := atmel_hlcdc_crtc.o \ + atmel_hlcdc_dc.o \ + atmel_hlcdc_layer.o \ + atmel_hlcdc_output.o \ + atmel_hlcdc_plane.o + +obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc-dc.o Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_crtc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/drm_crtc.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_crtc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:767 @ static void drm_mode_remove(struct drm_c } /** + * drm_display_info_set_bus_formats - set the supported bus formats + * @info: display info to store bus formats in + * @fmts: array containing the supported bus formats + * @nfmts: the number of entries in the fmts array + * + * Store the supported bus formats in display info structure. + * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for + * a full list of available formats. + */ +int drm_display_info_set_bus_formats(struct drm_display_info *info, + const u32 *formats, + unsigned int num_formats) +{ + u32 *fmts = NULL; + + if (!formats && num_formats) + return -EINVAL; + + if (formats && num_formats) { + fmts = kmemdup(formats, sizeof(*formats) * num_formats, + GFP_KERNEL); + if (!formats) + return -ENOMEM; + } + + kfree(info->bus_formats); + info->bus_formats = fmts; + info->num_bus_formats = num_formats; + + return 0; +} +EXPORT_SYMBOL(drm_display_info_set_bus_formats); + +/** * drm_connector_get_cmdline_mode - reads the user's cmdline mode * @connector: connector to quwery * @mode: returned mode @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:951 @ void drm_connector_cleanup(struct drm_co ida_remove(&drm_connector_enum_list[connector->connector_type].ida, connector->connector_type_id); + kfree(connector->display_info.bus_formats); drm_mode_object_put(dev, &connector->base); kfree(connector->name); connector->name = NULL; Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_flip_work.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/drm_flip_work.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_flip_work.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:28 @ #include "drm_flip_work.h" /** + * drm_flip_work_allocate_task - allocate a flip-work task + * @data: data associated to the task + * @flags: allocator flags + * + * Allocate a drm_flip_task object and attach private data to it. + */ +struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags) +{ + struct drm_flip_task *task; + + task = kzalloc(sizeof(*task), flags); + if (task) + task->data = data; + + return task; +} +EXPORT_SYMBOL(drm_flip_work_allocate_task); + +/** + * drm_flip_work_queue_task - queue a specific task + * @work: the flip-work + * @task: the task to handle + * + * Queues task, that will later be run (passed back to drm_flip_func_t + * func) on a work queue after drm_flip_work_commit() is called. + */ +void drm_flip_work_queue_task(struct drm_flip_work *work, + struct drm_flip_task *task) +{ + unsigned long flags; + + spin_lock_irqsave(&work->lock, flags); + list_add_tail(&task->node, &work->queued); + spin_unlock_irqrestore(&work->lock, flags); +} +EXPORT_SYMBOL(drm_flip_work_queue_task); + +/** * drm_flip_work_queue - queue work * @work: the flip-work * @val: the value to queue @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:75 @ */ void drm_flip_work_queue(struct drm_flip_work *work, void *val) { - if (kfifo_put(&work->fifo, val)) { - atomic_inc(&work->pending); + struct drm_flip_task *task; + + task = drm_flip_work_allocate_task(val, + drm_can_sleep() ? GFP_KERNEL : GFP_ATOMIC); + if (task) { + drm_flip_work_queue_task(work, task); } else { - DRM_ERROR("%s fifo full!\n", work->name); + DRM_ERROR("%s could not allocate task!\n", work->name); work->func(work, val); } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:101 @ EXPORT_SYMBOL(drm_flip_work_queue); void drm_flip_work_commit(struct drm_flip_work *work, struct workqueue_struct *wq) { - uint32_t pending = atomic_read(&work->pending); - atomic_add(pending, &work->count); - atomic_sub(pending, &work->pending); + unsigned long flags; + + spin_lock_irqsave(&work->lock, flags); + list_splice_tail(&work->queued, &work->commited); + INIT_LIST_HEAD(&work->queued); + spin_unlock_irqrestore(&work->lock, flags); queue_work(wq, &work->worker); } EXPORT_SYMBOL(drm_flip_work_commit); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:114 @ EXPORT_SYMBOL(drm_flip_work_commit); static void flip_worker(struct work_struct *w) { struct drm_flip_work *work = container_of(w, struct drm_flip_work, worker); - uint32_t count = atomic_read(&work->count); - void *val = NULL; + struct list_head tasks; + unsigned long flags; - atomic_sub(count, &work->count); + while (1) { + struct drm_flip_task *task, *tmp; - while(count--) - if (!WARN_ON(!kfifo_get(&work->fifo, &val))) - work->func(work, val); + INIT_LIST_HEAD(&tasks); + spin_lock_irqsave(&work->lock, flags); + list_splice_tail(&work->commited, &tasks); + INIT_LIST_HEAD(&work->commited); + spin_unlock_irqrestore(&work->lock, flags); + + if (list_empty(&tasks)) + break; + + list_for_each_entry_safe(task, tmp, &tasks, node) { + work->func(work, task->data); + kfree(task); + } + } } /** * drm_flip_work_init - initialize flip-work * @work: the flip-work to initialize - * @size: the max queue depth * @name: debug name * @func: the callback work function * * Initializes/allocates resources for the flip-work - * - * RETURNS: - * Zero on success, error code on failure. */ -int drm_flip_work_init(struct drm_flip_work *work, int size, +void drm_flip_work_init(struct drm_flip_work *work, const char *name, drm_flip_func_t func) { - int ret; - work->name = name; - atomic_set(&work->count, 0); - atomic_set(&work->pending, 0); + INIT_LIST_HEAD(&work->queued); + INIT_LIST_HEAD(&work->commited); + spin_lock_init(&work->lock); work->func = func; - ret = kfifo_alloc(&work->fifo, size, GFP_KERNEL); - if (ret) { - DRM_ERROR("could not allocate %s fifo\n", name); - return ret; - } - INIT_WORK(&work->worker, flip_worker); - - return 0; } EXPORT_SYMBOL(drm_flip_work_init); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:165 @ EXPORT_SYMBOL(drm_flip_work_init); */ void drm_flip_work_cleanup(struct drm_flip_work *work) { - WARN_ON(!kfifo_is_empty(&work->fifo)); - kfifo_free(&work->fifo); + WARN_ON(!list_empty(&work->queued) || !list_empty(&work->commited)); } EXPORT_SYMBOL(drm_flip_work_cleanup); Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_probe_helper.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/drm_probe_helper.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/drm_probe_helper.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:270 @ void drm_kms_helper_hotplug_event(struct } EXPORT_SYMBOL(drm_kms_helper_hotplug_event); -#define DRM_OUTPUT_POLL_PERIOD (10*HZ) +#define DRM_OUTPUT_POLL_PERIOD (4*HZ) static void output_poll_execute(struct work_struct *work) { struct delayed_work *delayed_work = to_delayed_work(work); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:294 @ static void output_poll_execute(struct w if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD) continue; - repoll = true; - old_status = connector->status; /* if we are connected and don't want to poll for disconnect skip it */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:301 @ static void output_poll_execute(struct w !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) continue; + repoll = true; + connector->status = connector->funcs->detect(connector, false); if (old_status != connector->status) { const char *old, *new; Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/i2c/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:22 @ config DRM_I2C_SIL164 when used in pairs) TMDS transmitters, used in some nVidia video cards. +config DRM_I2C_SIL902X + tristate "Silicon Image sil902x TMDS transmitters" + select REGMAP_I2C + help + Support for sil902x and similar single-link (or dual-link + when used in pairs) TMDS transmitters. + config DRM_I2C_NXP_TDA998X tristate "NXP Semiconductors TDA998X HDMI encoder" default m if DRM_TILCDC Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/i2c/Makefile +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:9 @ obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o sil164-y := sil164_drv.o obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o +obj-$(CONFIG_DRM_I2C_SIL902X) += sil902x.o + tda998x-y := tda998x_drv.o obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/sil902x.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/i2c/sil902x.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include <linux/component.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/regmap.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_encoder_slave.h> + +#define SIL902X_TPI_VIDEO_DATA 0x0 + +#define SIL902X_TPI_PIXEL_REPETITION 0x8 +#define SIL902X_TPI_AVI_PIXEL_REP_BUS_24BIT BIT(5) +#define SIL902X_TPI_AVI_PIXEL_REP_RISING_EDGE BIT(4) +#define SIL902X_TPI_AVI_PIXEL_REP_4X 3 +#define SIL902X_TPI_AVI_PIXEL_REP_2X 1 +#define SIL902X_TPI_AVI_PIXEL_REP_NONE 0 +#define SIL902X_TPI_CLK_RATIO_HALF (0 << 6) +#define SIL902X_TPI_CLK_RATIO_1X (1 << 6) +#define SIL902X_TPI_CLK_RATIO_2X (2 << 6) +#define SIL902X_TPI_CLK_RATIO_4X (3 << 6) + +#define SIL902X_TPI_AVI_IN_FORMAT 0x9 +#define SIL902X_TPI_AVI_INPUT_BITMODE_12BIT BIT(7) +#define SIL902X_TPI_AVI_INPUT_DITHER BIT(6) +#define SIL902X_TPI_AVI_INPUT_RANGE_LIMITED (2 << 2) +#define SIL902X_TPI_AVI_INPUT_RANGE_FULL (1 << 2) +#define SIL902X_TPI_AVI_INPUT_RANGE_AUTO (0 << 2) +#define SIL902X_TPI_AVI_INPUT_COLORSPACE_BLACK (3 << 0) +#define SIL902X_TPI_AVI_INPUT_COLORSPACE_YUV422 (2 << 0) +#define SIL902X_TPI_AVI_INPUT_COLORSPACE_YUV444 (1 << 0) +#define SIL902X_TPI_AVI_INPUT_COLORSPACE_RGB (0 << 0) + + +#define SIL902X_SYS_CTRL_DATA 0x1a +#define SIL902X_SYS_CTRL_PWR_DWN BIT(4) +#define SIL902X_SYS_CTRL_AV_MUTE BIT(3) +#define SIL902X_SYS_CTRL_DDC_BUS_REQ BIT(2) +#define SIL902X_SYS_CTRL_DDC_BUS_GRTD BIT(1) +#define SIL902X_SYS_CTRL_OUTPUT_MODE BIT(0) +#define SIL902X_SYS_CTRL_OUTPUT_HDMI 1 +#define SIL902X_SYS_CTRL_OUTPUT_DVI 0 + +#define SIL902X_REG_CHIPID(n) (0x1b + (n)) + +#define SIL902X_PWR_STATE_CTRL 0x1e +#define SIL902X_AVI_POWER_STATE_MSK GENMASK(1, 0) +#define SIL902X_AVI_POWER_STATE_D(l) ((l) & SIL902X_AVI_POWER_STATE_MSK) + +#define SI902X_INT_ENABLE 0x3c +#define SI902X_INT_STATUS 0x3d +#define SI902X_HOTPLUG_EVENT BIT(0) +#define SI902X_PLUGGED_STATUS BIT(2) + +#define SIL902X_REG_TPI_RQB 0xc7 + +struct sil902x { + struct i2c_client *i2c; + struct regmap *regmap; + struct drm_encoder encoder; + struct drm_connector connector; + int reset_gpio; + bool reset_active_low; + enum of_gpio_flags reset_gpio_flags; + struct work_struct hotplug_work; +}; + +static inline struct sil902x *encoder_to_sil902x(struct drm_encoder *encoder) +{ + return container_of(encoder, struct sil902x, encoder); +} + +static inline struct sil902x *connector_to_sil902x(struct drm_connector *con) +{ + return container_of(con, struct sil902x, connector); +} + +static void sil902x_reset(struct sil902x *sil902x) +{ + if (!gpio_is_valid(sil902x->reset_gpio)) + return; + + gpio_set_value(sil902x->reset_gpio, + sil902x->reset_active_low ? 0 : 1); + + msleep(100); + + gpio_set_value(sil902x->reset_gpio, + sil902x->reset_active_low ? 1 : 0); +} + +static void sil902x_encoder_reset(struct drm_encoder *encoder) +{ + struct sil902x *sil902x = encoder_to_sil902x(encoder); + + sil902x_reset(sil902x); +} + +static void sil902x_encoder_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs sil902x_encoder_funcs = { + .reset = sil902x_encoder_reset, + .destroy = sil902x_encoder_destroy, +}; + +static void sil902x_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct sil902x *sil902x = encoder_to_sil902x(encoder); + + switch (mode) { + case DRM_MODE_DPMS_ON: + regmap_update_bits(sil902x->regmap, SIL902X_PWR_STATE_CTRL, + SIL902X_AVI_POWER_STATE_MSK, + SIL902X_AVI_POWER_STATE_D(0)); + regmap_update_bits(sil902x->regmap, SIL902X_SYS_CTRL_DATA, + SIL902X_SYS_CTRL_PWR_DWN, 0); + break; + case DRM_MODE_DPMS_OFF: + regmap_update_bits(sil902x->regmap, SIL902X_SYS_CTRL_DATA, + SIL902X_SYS_CTRL_PWR_DWN, + SIL902X_SYS_CTRL_PWR_DWN); + break; + } +} + +static void sil902x_encoder_save(struct drm_encoder *encoder) +{ + /* TODO: save registers values */ +} + +static void sil902x_encoder_restore(struct drm_encoder *encoder) +{ + /* TODO: restore registers values */ +} + +static bool sil902x_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + /* TODO: see if we can implement a proper mode fixup here */ + + return true; +} + +static void sil902x_encoder_prepare(struct drm_encoder *encoder) +{ + sil902x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); +} + +static void sil902x_encoder_commit(struct drm_encoder *encoder) +{ + sil902x_encoder_dpms(encoder, DRM_MODE_DPMS_ON); +} + +static void sil902x_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct sil902x *sil902x = encoder_to_sil902x(encoder); + struct regmap * regmap = sil902x->regmap; + u8 buf[10]; + int ret; + + buf[0] = adjusted_mode->clock; + buf[1] = adjusted_mode->clock >> 8; + buf[2] = 0x3c; + buf[3] = 0x60; + buf[4] = adjusted_mode->hdisplay; + buf[5] = adjusted_mode->hdisplay >> 8; + buf[6] = adjusted_mode->vdisplay; + buf[7] = adjusted_mode->vdisplay >> 8; + buf[8] = SIL902X_TPI_CLK_RATIO_1X | SIL902X_TPI_AVI_PIXEL_REP_NONE | + SIL902X_TPI_AVI_PIXEL_REP_BUS_24BIT; + buf[9] = SIL902X_TPI_AVI_INPUT_RANGE_AUTO | + SIL902X_TPI_AVI_INPUT_COLORSPACE_RGB; + + ret = regmap_bulk_write(regmap, SIL902X_TPI_VIDEO_DATA, buf, 10); + if (ret) + return; +} + +static const struct drm_encoder_helper_funcs sil902x_encoder_helper_funcs = { + .dpms = sil902x_encoder_dpms, + .save = sil902x_encoder_save, + .restore = sil902x_encoder_restore, + .mode_fixup = sil902x_encoder_mode_fixup, + .prepare = sil902x_encoder_prepare, + .commit = sil902x_encoder_commit, + .mode_set = sil902x_encoder_mode_set, +}; + +static void sil902x_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static enum drm_connector_status +sil902x_connector_detect(struct drm_connector *connector, bool force) +{ + struct sil902x *sil902x = connector_to_sil902x(connector); + unsigned int status; + + regmap_read(sil902x->regmap, SI902X_INT_STATUS, &status); + + return (status & SI902X_PLUGGED_STATUS) ? + connector_status_connected : connector_status_disconnected; +} + +static const struct drm_connector_funcs sil902x_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .detect = sil902x_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = sil902x_connector_destroy, +}; + +static int sil902x_get_modes(struct drm_connector *connector) +{ + struct sil902x *sil902x = connector_to_sil902x(connector); + struct regmap *regmap = sil902x->regmap; + u32 bus_fomart = MEDIA_BUS_FMT_RGB888_1X24; + unsigned int status; + struct edid *edid; + int num = 0; + int ret; + int i; + + ret = regmap_update_bits(regmap, SIL902X_PWR_STATE_CTRL, + SIL902X_AVI_POWER_STATE_MSK, + SIL902X_AVI_POWER_STATE_D(2)); + if (ret) + return ret; + + ret = regmap_write(regmap, SIL902X_SYS_CTRL_DATA, + SIL902X_SYS_CTRL_OUTPUT_HDMI | + SIL902X_SYS_CTRL_PWR_DWN); + if (ret) + return ret; + + ret = regmap_update_bits(regmap, SIL902X_SYS_CTRL_DATA, + SIL902X_SYS_CTRL_DDC_BUS_REQ, + SIL902X_SYS_CTRL_DDC_BUS_REQ); + if (ret) + return ret; + + i = 0; + do { + ret = regmap_read(regmap, SIL902X_SYS_CTRL_DATA, &status); + if (ret) + return ret; + i++; + } while (!(status & SIL902X_SYS_CTRL_DDC_BUS_GRTD)); + + ret = regmap_write(regmap, SIL902X_SYS_CTRL_DATA, status); + if (ret) + return ret; + + edid = drm_get_edid(connector, sil902x->i2c->adapter); + drm_mode_connector_update_edid_property(connector, edid); + if (edid) { + num += drm_add_edid_modes(connector, edid); + kfree(edid); + } + + ret = drm_display_info_set_bus_formats(&connector->display_info, + &bus_fomart, 1); + if (ret) + return ret; + + regmap_read(regmap, SIL902X_SYS_CTRL_DATA, &status); + if (ret) + return ret; + + ret = regmap_update_bits(regmap, SIL902X_SYS_CTRL_DATA, + SIL902X_SYS_CTRL_DDC_BUS_REQ | + SIL902X_SYS_CTRL_DDC_BUS_GRTD, 0); + if (ret) + return ret; + + i = 0; + do { + ret = regmap_read(regmap, SIL902X_SYS_CTRL_DATA, &status); + if (ret) + return ret; + i++; + } while (status & (SIL902X_SYS_CTRL_DDC_BUS_REQ | + SIL902X_SYS_CTRL_DDC_BUS_GRTD)); + + return num; +} + +static enum drm_mode_status sil902x_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + /* TODO: check mode */ + + return MODE_OK; +} + +static struct drm_encoder *sil902x_best_encoder(struct drm_connector *connector) +{ + struct sil902x *sil902x = connector_to_sil902x(connector); + + return &sil902x->encoder; +} + +static const struct drm_connector_helper_funcs sil902x_connector_helper_funcs = { + .get_modes = sil902x_get_modes, + .mode_valid = sil902x_mode_valid, + .best_encoder = sil902x_best_encoder, +}; + +static const struct regmap_range sil902x_volatile_ranges[] = { + { + .range_min = 0, + .range_max = 0xff, + }, +}; + +static const struct regmap_access_table sil902x_volatile_table = { + .yes_ranges = sil902x_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(sil902x_volatile_ranges), +}; + + +static const struct regmap_config sil902x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = &sil902x_volatile_table, + .cache_type = REGCACHE_NONE, +}; + +static int sil902x_bind(struct device *dev, struct device *master, void *data) +{ + struct sil902x *sil902x = dev_get_drvdata(dev); + struct drm_device *drm = data; + int ret; + + sil902x->encoder.possible_crtcs = 1; + drm_encoder_helper_add(&sil902x->encoder, &sil902x_encoder_helper_funcs); + ret = drm_encoder_init(drm, &sil902x->encoder, &sil902x_encoder_funcs, + DRM_MODE_ENCODER_TMDS); + if (ret) + return ret; + + drm_connector_helper_add(&sil902x->connector, + &sil902x_connector_helper_funcs); + ret = drm_connector_init(drm, &sil902x->connector, + &sil902x_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); + if (ret) + goto err_cleanup_encoder; + + if (sil902x->i2c->irq > 0) + sil902x->connector.polled = DRM_CONNECTOR_POLL_HPD; + else + sil902x->connector.polled = DRM_CONNECTOR_POLL_CONNECT; + + drm_mode_connector_attach_encoder(&sil902x->connector, &sil902x->encoder); + + return 0; + +err_cleanup_encoder: + drm_encoder_cleanup(&sil902x->encoder); + + return ret; +} + +static void sil902x_unbind(struct device *dev, struct device *master, void *data) +{ + struct sil902x *sil902x = dev_get_drvdata(dev); + + drm_connector_cleanup(&sil902x->connector); + drm_encoder_cleanup(&sil902x->encoder); +} + +static const struct component_ops sil902x_ops = { + .bind = sil902x_bind, + .unbind = sil902x_unbind, +}; + +static irqreturn_t sil902x_interrupt(int irq, void *data) +{ + struct sil902x *sil902x = data; + unsigned int status = 0; + + regmap_read(sil902x->regmap, SI902X_INT_STATUS, &status); + regmap_write(sil902x->regmap, SI902X_INT_STATUS, status); + + if ((status & SI902X_HOTPLUG_EVENT) && sil902x->encoder.dev) + drm_helper_hpd_irq_event(sil902x->encoder.dev); + + return IRQ_HANDLED; +} + +static int sil902x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + enum of_gpio_flags gpio_flags; + unsigned int status = 0; + struct sil902x *sil902x; + u8 chipid[4]; + int ret; + + sil902x = devm_kzalloc(dev, sizeof(*sil902x), GFP_KERNEL); + if (!sil902x) + return -ENOMEM; + + sil902x->i2c = client; + sil902x->regmap = devm_regmap_init_i2c(client, &sil902x_regmap_config); + if (IS_ERR(sil902x->regmap)) + return PTR_ERR(sil902x->regmap); + + sil902x->reset_gpio = of_get_named_gpio_flags(dev->of_node, + "reset-gpios", 0, + &gpio_flags); + if (gpio_flags & OF_GPIO_ACTIVE_LOW) + sil902x->reset_active_low = true; + + if (gpio_is_valid(sil902x->reset_gpio)) { + ret = devm_gpio_request(dev, sil902x->reset_gpio, "reset-gpio"); + if (ret) + return ret; + sil902x->reset_active_low = true; + + ret = gpio_direction_output(sil902x->reset_gpio, + sil902x->reset_active_low ? 1 : 0); + if (ret) + return ret; + + sil902x_reset(sil902x); + } + + ret = regmap_write(sil902x->regmap, SIL902X_REG_TPI_RQB, 0x0); + if (ret) + return ret; + + ret = regmap_bulk_read(sil902x->regmap, SIL902X_REG_CHIPID(0), + &chipid, 4); + if (ret) { + dev_err(dev, "regmap_read failed %d\n", ret); + return ret; + } + + if (chipid[0] != 0xb0) { + dev_err(dev, "Invalid chipid: %02x (expecting 0xb0)\n", + chipid[0]); + return -EINVAL; + } + + /* Clear all pending interrupts */ + regmap_read(sil902x->regmap, SI902X_INT_STATUS, &status); + regmap_write(sil902x->regmap, SI902X_INT_STATUS, status); + + if (client->irq > 0) { + regmap_write(sil902x->regmap, SI902X_INT_ENABLE, + SI902X_HOTPLUG_EVENT); + + ret = devm_request_threaded_irq(dev, client->irq, NULL, + sil902x_interrupt, + IRQF_ONESHOT, dev_name(dev), + sil902x); + if (ret) + return ret; + } + + i2c_set_clientdata(client, sil902x); + + return component_add(&client->dev, &sil902x_ops); +} + + +static int sil902x_i2c_remove(struct i2c_client *client) + +{ + component_del(&client->dev, &sil902x_ops); + + return 0; +} + +static int sil902x_encoder_init(struct i2c_client *client, + struct drm_device *dev, + struct drm_encoder_slave *encoder) +{ + return 0; +} + + +#ifdef CONFIG_OF +static const struct of_device_id sil902x_i2c_dt_ids[] = { + { .compatible = "sil,sil9022", }, + { } +}; +MODULE_DEVICE_TABLE(of, sil902x_i2c_dt_ids); +#endif + +static const struct i2c_device_id sil902x_i2c_ids[] = { + { "sil9022", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, sil9022_id); + +static struct drm_i2c_encoder_driver sil902x_i2c_driver = { + .i2c_driver = { + .probe = sil902x_i2c_probe, + .remove = sil902x_i2c_remove, + .driver = { + .name = "sil902x", + .of_match_table = of_match_ptr(sil902x_i2c_dt_ids), + }, + .id_table = sil902x_i2c_ids, + }, + + .encoder_init = sil902x_encoder_init, +}; + +static int __init +sil902x_init(void) +{ + return drm_i2c_encoder_register(THIS_MODULE, &sil902x_i2c_driver); +} +module_init(sil902x_init); + +static void __exit +sil902x_exit(void) +{ + drm_i2c_encoder_unregister(&sil902x_i2c_driver); +} +module_exit(sil902x_exit); + +MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); +MODULE_DESCRIPTION("SIL902X TMDS encoders"); +MODULE_LICENSE("GPL"); Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:184 @ source "drivers/gpu/drm/cirrus/Kconfig" source "drivers/gpu/drm/armada/Kconfig" +source "drivers/gpu/drm/atmel-hlcdc/Kconfig" + source "drivers/gpu/drm/rcar-du/Kconfig" source "drivers/gpu/drm/shmobile/Kconfig" Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/Makefile +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:56 @ obj-$(CONFIG_DRM_GMA500) += gma500/ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_ARMADA) += armada/ +obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:760 @ struct drm_crtc *mdp4_crtc_init(struct d { struct drm_crtc *crtc = NULL; struct mdp4_crtc *mdp4_crtc; - int ret; mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL); - if (!mdp4_crtc) { - ret = -ENOMEM; - goto fail; - } + if (!mdp4_crtc) + return ERR_PTR(-ENOMEM); crtc = &mdp4_crtc->base; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:784 @ struct drm_crtc *mdp4_crtc_init(struct d spin_lock_init(&mdp4_crtc->cursor.lock); - ret = drm_flip_work_init(&mdp4_crtc->unref_fb_work, 16, + drm_flip_work_init(&mdp4_crtc->unref_fb_work, "unref fb", unref_fb_worker); - if (ret) - goto fail; - - ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64, + drm_flip_work_init(&mdp4_crtc->unref_cursor_work, "unref cursor", unref_cursor_worker); INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:797 @ struct drm_crtc *mdp4_crtc_init(struct d mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base); return crtc; - -fail: - if (crtc) - mdp4_crtc_destroy(crtc); - - return ERR_PTR(ret); } Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:537 @ struct drm_crtc *mdp5_crtc_init(struct d { struct drm_crtc *crtc = NULL; struct mdp5_crtc *mdp5_crtc; - int ret; mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL); - if (!mdp5_crtc) { - ret = -ENOMEM; - goto fail; - } + if (!mdp5_crtc) + return ERR_PTR(-ENOMEM); crtc = &mdp5_crtc->base; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:553 @ struct drm_crtc *mdp5_crtc_init(struct d snprintf(mdp5_crtc->name, sizeof(mdp5_crtc->name), "%s:%d", pipe2name(mdp5_plane_pipe(plane)), id); - ret = drm_flip_work_init(&mdp5_crtc->unref_fb_work, 16, + drm_flip_work_init(&mdp5_crtc->unref_fb_work, "unref fb", unref_fb_worker); - if (ret) - goto fail; INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:564 @ struct drm_crtc *mdp5_crtc_init(struct d mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base); return crtc; - -fail: - if (crtc) - mdp5_crtc_destroy(crtc); - - return ERR_PTR(ret); } Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/omapdrm/omap_plane.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/omapdrm/omap_plane.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/omapdrm/omap_plane.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:397 @ struct drm_plane *omap_plane_init(struct omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); if (!omap_plane) - goto fail; + return NULL; - ret = drm_flip_work_init(&omap_plane->unpin_work, 16, + drm_flip_work_init(&omap_plane->unpin_work, "unpin", unpin_worker); - if (ret) { - dev_err(dev->dev, "could not allocate unpin FIFO\n"); - goto fail; - } omap_plane->nformats = omap_framebuffer_get_formats( omap_plane->formats, ARRAY_SIZE(omap_plane->formats), @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:442 @ struct drm_plane *omap_plane_init(struct omap_plane->info.zorder = id; return plane; - -fail: - if (plane) - omap_plane_destroy(plane); - - return NULL; } Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/panel/panel-simple.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/panel/panel-simple.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/panel/panel-simple.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:64 @ struct panel_desc { unsigned int disable; unsigned int unprepare; } delay; + + u32 bus_format; }; struct panel_simple { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:107 @ static int panel_simple_get_fixed_modes( continue; } + mode->type |= DRM_MODE_TYPE_DRIVER; + if (panel->desc->num_modes == 1) + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); drm_mode_probed_add(connector, mode); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:120 @ static int panel_simple_get_fixed_modes( connector->display_info.bpc = panel->desc->bpc; connector->display_info.width_mm = panel->desc->size.width; connector->display_info.height_mm = panel->desc->size.height; + if (panel->desc->bus_format) + drm_display_info_set_bus_formats(&connector->display_info, + &panel->desc->bus_format, 1); return num; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:552 @ static const struct panel_desc foxlink_f .width = 108, .height = 65, }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, +}; + +static const struct drm_display_mode innolux_at043tn24_mode = { + .clock = 9000, + .hdisplay = 480, + .hsync_start = 480 + 2, + .hsync_end = 480 + 2 + 41, + .htotal = 480 + 2 + 41 + 2, + .vdisplay = 272, + .vsync_start = 272 + 2, + .vsync_end = 272 + 2 + 11, + .vtotal = 272 + 2 + 11 + 2, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct panel_desc innolux_at043tn24 = { + .modes = &innolux_at043tn24_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; static const struct drm_display_mode innolux_n116bge_mode = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:650 @ static const struct panel_desc lg_lp129q }, }; +static const struct drm_display_mode qd43003c0_40_mode = { + .clock = 9000, + .hdisplay = 480, + .hsync_start = 480 + 8, + .hsync_end = 480 + 8 + 4, + .htotal = 480 + 8 + 4 + 39, + .vdisplay = 272, + .vsync_start = 272 + 4, + .vsync_end = 272 + 4 + 10, + .vtotal = 272 + 4 + 10 + 2, + .vrefresh = 60, +}; + +static const struct panel_desc qd43003c0_40 = { + .modes = &qd43003c0_40_mode, + .num_modes = 1, + .size = { + .width = 95, + .height = 53, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, +}; + static const struct drm_display_mode samsung_ltn101nt05_mode = { .clock = 54030, .hdisplay = 1024, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:696 @ static const struct panel_desc samsung_l }, }; + +static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = { + .clock = 33300, + .hdisplay = 800, + .hsync_start = 800 + 1, + .hsync_end = 800 + 1 + 64, + .htotal = 800 + 1 + 64 + 64, + .vdisplay = 480, + .vsync_start = 480 + 1, + .vsync_end = 480 + 1 + 23, + .vtotal = 480 + 1 + 23 + 22, + .vrefresh = 60, +}; + +static const struct panel_desc shelly_sca07010_bfn_lnn = { + .modes = &shelly_sca07010_bfn_lnn_mode, + .num_modes = 1, + .size = { + .width = 152, + .height = 91, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, +}; + static const struct of_device_id platform_of_match[] = { { .compatible = "auo,b101aw03", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:752 @ static const struct of_device_id platfor .compatible = "foxlink,fl500wvr00-a0t", .data = &foxlink_fl500wvr00_a0t, }, { + .compatible = "innolux,at043tn24", + .data = &innolux_at043tn24, + }, { .compatible = "innolux,n116bge", .data = &innolux_n116bge, }, { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:764 @ static const struct of_device_id platfor .compatible = "lg,lp129qe", .data = &lg_lp129qe, }, { + .compatible = "qd,qd43003c0-40", + .data = &qd43003c0_40, + }, { .compatible = "samsung,ltn101nt05", .data = &samsung_ltn101nt05, }, { + .compatible = "shelly,sca07010-bfn-lnn", + .data = &shelly_sca07010_bfn_lnn, + }, { /* sentinel */ } }; Index: linux-3.18.13-rt10-r7s4/drivers/gpu/drm/tilcdc/tilcdc_crtc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:667 @ struct drm_crtc *tilcdc_crtc_create(stru tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; init_waitqueue_head(&tilcdc_crtc->frame_done_wq); - ret = drm_flip_work_init(&tilcdc_crtc->unref_work, 16, + drm_flip_work_init(&tilcdc_crtc->unref_work, "unref", unref_worker); - if (ret) { - dev_err(dev->dev, "could not allocate unref FIFO\n"); - goto fail; - } ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); if (ret < 0) Index: linux-3.18.13-rt10-r7s4/drivers/gpu/ipu-v3/ipu-csi.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/gpu/ipu-v3/ipu-csi.c +++ linux-3.18.13-rt10-r7s4/drivers/gpu/ipu-v3/ipu-csi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:230 @ static int ipu_csi_set_testgen_mclk(stru static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) { switch (mbus_code) { - case V4L2_MBUS_FMT_BGR565_2X8_BE: - case V4L2_MBUS_FMT_BGR565_2X8_LE: - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_BGR565_2X8_BE: + case MEDIA_BUS_FMT_BGR565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565; cfg->mipi_dt = MIPI_DT_RGB565; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB444; cfg->mipi_dt = MIPI_DT_RGB444; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555; cfg->mipi_dt = MIPI_DT_RGB555; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_16; break; - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_16; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGBRG8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: - case V4L2_MBUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW8; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW10; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SGBRG10_1X10: - case V4L2_MBUS_FMT_SGRBG10_1X10: - case V4L2_MBUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW10; cfg->data_width = IPU_CSI_DATA_WIDTH_10; break; - case V4L2_MBUS_FMT_SBGGR12_1X12: - case V4L2_MBUS_FMT_SGBRG12_1X12: - case V4L2_MBUS_FMT_SGRBG12_1X12: - case V4L2_MBUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW12; cfg->data_width = IPU_CSI_DATA_WIDTH_12; break; - case V4L2_MBUS_FMT_JPEG_1X8: + case MEDIA_BUS_FMT_JPEG_1X8: /* TODO */ cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_JPEG; cfg->mipi_dt = MIPI_DT_RAW8; Index: linux-3.18.13-rt10-r7s4/drivers/i2c/busses/i2c-at91.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/i2c/busses/i2c-at91.c +++ linux-3.18.13-rt10-r7s4/drivers/i2c/busses/i2c-at91.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:34 @ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/platform_data/dma-atmel.h> +#include <linux/pm_runtime.h> +#include <linux/pinctrl/consumer.h> #define DEFAULT_TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ #define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ +#define AUTOSUSPEND_TIMEOUT 2000 /* AT91 TWI register definitions */ #define AT91_TWI_CR 0x0000 /* Control Register */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ struct at91_twi_pdata { unsigned clk_max_div; unsigned clk_offset; bool has_unre_flag; - bool has_dma_support; struct at_dma_slave dma_slave; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:486 @ static int at91_twi_xfer(struct i2c_adap dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto out; + /* * The hardware can handle at most two messages concatenated by a * repeated start via it's internal address feature. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:497 @ static int at91_twi_xfer(struct i2c_adap if (num > 2) { dev_err(dev->dev, "cannot handle more than two concatenated messages.\n"); - return 0; + ret = 0; + goto out; } else if (num == 2) { int internal_address = 0; int i; if (msg->flags & I2C_M_RD) { dev_err(dev->dev, "first transfer must be write.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } if (msg->len > 3) { dev_err(dev->dev, "first message size must be <= 3.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* 1st msg is put into the internal address, start with 2nd */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:535 @ static int at91_twi_xfer(struct i2c_adap ret = at91_do_twi_transfer(dev); - return (ret < 0) ? ret : num; + ret = (ret < 0) ? ret : num; +out: + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + + return ret; } static u32 at91_twi_func(struct i2c_adapter *adapter) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:558 @ static struct at91_twi_pdata at91rm9200_ .clk_max_div = 5, .clk_offset = 3, .has_unre_flag = true, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9261_config = { .clk_max_div = 5, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9260_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9g20_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9g10_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static const struct platform_device_id at91_twi_devtypes[] = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:610 @ static struct at91_twi_pdata at91sam9x5_ .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = true, }; static const struct of_device_id atmel_twi_dt_ids[] = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:638 @ static const struct of_device_id atmel_t MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids); #endif -static bool filter(struct dma_chan *chan, void *pdata) -{ - struct at91_twi_pdata *sl_pdata = pdata; - struct at_dma_slave *sl; - - if (!sl_pdata) - return false; - - sl = &sl_pdata->dma_slave; - if (sl && (sl->dma_dev == chan->device->dev)) { - chan->private = sl; - return true; - } else { - return false; - } -} - static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) { int ret = 0; - struct at91_twi_pdata *pdata = dev->pdata; struct dma_slave_config slave_config; struct at91_twi_dma *dma = &dev->dma; - dma_cap_mask_t mask; memset(&slave_config, 0, sizeof(slave_config)); slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:653 @ static int at91_twi_configure_dma(struct slave_config.dst_maxburst = 1; slave_config.device_fc = false; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - dma->chan_tx = dma_request_slave_channel_compat(mask, filter, pdata, - dev->dev, "tx"); - if (!dma->chan_tx) { - dev_err(dev->dev, "can't get a DMA channel for tx\n"); - ret = -EBUSY; + dma->chan_tx = dma_request_slave_channel_reason(dev->dev, "tx"); + if (IS_ERR(dma->chan_tx)) { + ret = PTR_ERR(dma->chan_tx); + dma->chan_tx = NULL; goto error; } - dma->chan_rx = dma_request_slave_channel_compat(mask, filter, pdata, - dev->dev, "rx"); - if (!dma->chan_rx) { - dev_err(dev->dev, "can't get a DMA channel for rx\n"); - ret = -EBUSY; + dma->chan_rx = dma_request_slave_channel_reason(dev->dev, "rx"); + if (IS_ERR(dma->chan_rx)) { + ret = PTR_ERR(dma->chan_rx); + dma->chan_rx = NULL; goto error; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:684 @ static int at91_twi_configure_dma(struct sg_init_table(&dma->sg, 1); dma->buf_mapped = false; dma->xfer_in_progress = false; + dev->use_dma = true; dev_info(dev->dev, "using %s (tx) and %s (rx) for DMA transfers\n", dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx)); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:692 @ static int at91_twi_configure_dma(struct return ret; error: - dev_info(dev->dev, "can't use DMA\n"); + if (ret != -EPROBE_DEFER) + dev_info(dev->dev, "can't use DMA, error %d\n", ret); if (dma->chan_rx) dma_release_channel(dma->chan_rx); if (dma->chan_tx) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:756 @ static int at91_twi_probe(struct platfor dev->clk = devm_clk_get(dev->dev, NULL); if (IS_ERR(dev->clk)) { - dev_err(dev->dev, "no clock defined\n"); - return -ENODEV; + rc = PTR_ERR(dev->clk); + if (rc != -EPROBE_DEFER) + dev_err(dev->dev, "no clock defined\n"); + return rc; } clk_prepare_enable(dev->clk); - if (dev->pdata->has_dma_support) { - if (at91_twi_configure_dma(dev, phy_addr) == 0) - dev->use_dma = true; + if (dev->dev->of_node) { + rc = at91_twi_configure_dma(dev, phy_addr); + if (rc == -EPROBE_DEFER) + return rc; } rc = of_property_read_u32(dev->dev->of_node, "clock-frequency", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:787 @ static int at91_twi_probe(struct platfor dev->adapter.timeout = AT91_I2C_TIMEOUT; dev->adapter.dev.of_node = pdev->dev.of_node; + pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev->dev); + pm_runtime_set_active(dev->dev); + pm_runtime_enable(dev->dev); + rc = i2c_add_numbered_adapter(&dev->adapter); if (rc) { dev_err(dev->dev, "Adapter %s registration failed\n", dev->adapter.name); clk_disable_unprepare(dev->clk); + + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return rc; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:815 @ static int at91_twi_remove(struct platfo i2c_del_adapter(&dev->adapter); clk_disable_unprepare(dev->clk); + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:827 @ static int at91_twi_runtime_suspend(stru { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - clk_disable(twi_dev->clk); + clk_disable_unprepare(twi_dev->clk); + + pinctrl_pm_select_sleep_state(dev); return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:838 @ static int at91_twi_runtime_resume(struc { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - return clk_enable(twi_dev->clk); + pinctrl_pm_select_default_state(dev); + + return clk_prepare_enable(twi_dev->clk); +} + +static int at91_twi_suspend_noirq(struct device *dev) +{ + if (!pm_runtime_status_suspended(dev)) + at91_twi_runtime_suspend(dev); + + return 0; +} + +static int at91_twi_resume_noirq(struct device *dev) +{ + int ret; + + if (!pm_runtime_status_suspended(dev)) { + ret = at91_twi_runtime_resume(dev); + if (ret) + return ret; + } + + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + + return 0; } static const struct dev_pm_ops at91_twi_pm = { + .suspend_noirq = at91_twi_suspend_noirq, + .resume_noirq = at91_twi_resume_noirq, .runtime_suspend = at91_twi_runtime_suspend, .runtime_resume = at91_twi_runtime_resume, }; Index: linux-3.18.13-rt10-r7s4/drivers/input/touchscreen/atmel_mxt_ts.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/input/touchscreen/atmel_mxt_ts.c +++ linux-3.18.13-rt10-r7s4/drivers/input/touchscreen/atmel_mxt_ts.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:26 @ #include <linux/i2c/atmel_mxt_ts.h> #include <linux/input/mt.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/of.h> #include <linux/slab.h> +#include <linux/regulator/consumer.h> +#include <linux/gpio.h> -/* Version */ -#define MXT_VER_20 20 -#define MXT_VER_21 21 -#define MXT_VER_22 22 - -/* Firmware files */ -#define MXT_FW_NAME "maxtouch.fw" -#define MXT_CFG_NAME "maxtouch.cfg" +#ifdef CONFIG_OF +#include <linux/of_gpio.h> +#endif + +/* Configuration file */ #define MXT_CFG_MAGIC "OBP_RAW V1" /* Registers */ -#define MXT_INFO 0x00 -#define MXT_FAMILY_ID 0x00 -#define MXT_VARIANT_ID 0x01 -#define MXT_VERSION 0x02 -#define MXT_BUILD 0x03 -#define MXT_MATRIX_X_SIZE 0x04 -#define MXT_MATRIX_Y_SIZE 0x05 -#define MXT_OBJECT_NUM 0x06 #define MXT_OBJECT_START 0x07 - #define MXT_OBJECT_SIZE 6 #define MXT_INFO_CHECKSUM_SIZE 3 -#define MXT_MAX_BLOCK_WRITE 256 +#define MXT_MAX_BLOCK_WRITE 255 /* Object types */ #define MXT_DEBUG_DIAGNOSTIC_T37 37 @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ #define MXT_SPT_DIGITIZER_T43 43 #define MXT_SPT_MESSAGECOUNT_T44 44 #define MXT_SPT_CTECONFIG_T46 46 +#define MXT_PROCI_ACTIVE_STYLUS_T63 63 +#define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71 +#define MXT_TOUCH_MULTITOUCHSCREEN_T100 100 +#define MXT_PROCI_ACTIVESTYLUS_T107 107 /* MXT_GEN_MESSAGE_T5 object */ #define MXT_RPTID_NOMSG 0xff @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:105 @ struct t7_config { #define MXT_POWER_CFG_RUN 0 #define MXT_POWER_CFG_DEEPSLEEP 1 -/* MXT_GEN_ACQUIRE_T8 field */ -#define MXT_ACQUIRE_CHRGTIME 0 -#define MXT_ACQUIRE_TCHDRIFT 2 -#define MXT_ACQUIRE_DRIFTST 3 -#define MXT_ACQUIRE_TCHAUTOCAL 4 -#define MXT_ACQUIRE_SYNC 5 -#define MXT_ACQUIRE_ATCHCALST 6 -#define MXT_ACQUIRE_ATCHCALSTHR 7 - /* MXT_TOUCH_MULTI_T9 field */ #define MXT_T9_ORIENT 9 #define MXT_T9_RANGE 18 @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:127 @ struct t9_range { /* MXT_TOUCH_MULTI_T9 orient */ #define MXT_T9_ORIENT_SWITCH (1 << 0) -/* MXT_PROCI_GRIPFACE_T20 field */ -#define MXT_GRIPFACE_CTRL 0 -#define MXT_GRIPFACE_XLOGRIP 1 -#define MXT_GRIPFACE_XHIGRIP 2 -#define MXT_GRIPFACE_YLOGRIP 3 -#define MXT_GRIPFACE_YHIGRIP 4 -#define MXT_GRIPFACE_MAXTCHS 5 -#define MXT_GRIPFACE_SZTHR1 7 -#define MXT_GRIPFACE_SZTHR2 8 -#define MXT_GRIPFACE_SHPTHR1 9 -#define MXT_GRIPFACE_SHPTHR2 10 -#define MXT_GRIPFACE_SUPEXTTO 11 - -/* MXT_PROCI_NOISE field */ -#define MXT_NOISE_CTRL 0 -#define MXT_NOISE_OUTFLEN 1 -#define MXT_NOISE_GCAFUL_LSB 3 -#define MXT_NOISE_GCAFUL_MSB 4 -#define MXT_NOISE_GCAFLL_LSB 5 -#define MXT_NOISE_GCAFLL_MSB 6 -#define MXT_NOISE_ACTVGCAFVALID 7 -#define MXT_NOISE_NOISETHR 8 -#define MXT_NOISE_FREQHOPSCALE 10 -#define MXT_NOISE_FREQ0 11 -#define MXT_NOISE_FREQ1 12 -#define MXT_NOISE_FREQ2 13 -#define MXT_NOISE_FREQ3 14 -#define MXT_NOISE_FREQ4 15 -#define MXT_NOISE_IDLEGCAFVALID 16 - /* MXT_SPT_COMMSCONFIG_T18 */ #define MXT_COMMS_CTRL 0 #define MXT_COMMS_CMD 1 - -/* MXT_SPT_CTECONFIG_T28 field */ -#define MXT_CTE_CTRL 0 -#define MXT_CTE_CMD 1 -#define MXT_CTE_MODE 2 -#define MXT_CTE_IDLEGCAFDEPTH 3 -#define MXT_CTE_ACTVGCAFDEPTH 4 -#define MXT_CTE_VOLTAGE 5 - -#define MXT_VOLTAGE_DEFAULT 2700000 -#define MXT_VOLTAGE_STEP 10000 +#define MXT_COMMS_RETRIGEN (1 << 6) /* Define for MXT_GEN_COMMAND_T6 */ #define MXT_BOOT_VALUE 0xa5 #define MXT_RESET_VALUE 0x01 #define MXT_BACKUP_VALUE 0x55 +/* Define for MXT_PROCI_TOUCHSUPPRESSION_T42 */ +#define MXT_T42_MSG_TCHSUP (1 << 0) + +/* T63 Stylus */ +#define MXT_T63_STYLUS_PRESS (1 << 0) +#define MXT_T63_STYLUS_RELEASE (1 << 1) +#define MXT_T63_STYLUS_MOVE (1 << 2) +#define MXT_T63_STYLUS_SUPPRESS (1 << 3) + +#define MXT_T63_STYLUS_DETECT (1 << 4) +#define MXT_T63_STYLUS_TIP (1 << 5) +#define MXT_T63_STYLUS_ERASER (1 << 6) +#define MXT_T63_STYLUS_BARREL (1 << 7) + +#define MXT_T63_STYLUS_PRESSURE_MASK 0x3F + +/* T100 Multiple Touch Touchscreen */ +#define MXT_T100_CTRL 0 +#define MXT_T100_CFG1 1 +#define MXT_T100_TCHAUX 3 +#define MXT_T100_XRANGE 13 +#define MXT_T100_YRANGE 24 + +#define MXT_T100_CFG_SWITCHXY (1 << 5) + +#define MXT_T100_TCHAUX_VECT (1 << 0) +#define MXT_T100_TCHAUX_AMPL (1 << 1) +#define MXT_T100_TCHAUX_AREA (1 << 2) + +#define MXT_T100_DETECT (1 << 7) +#define MXT_T100_TYPE_MASK 0x70 + +enum t100_type { + MXT_T100_TYPE_FINGER = 1, + MXT_T100_TYPE_PASSIVE_STYLUS = 2, + MXT_T100_TYPE_ACTIVE_STYLUS = 3, + MXT_T100_TYPE_HOVERING_FINGER = 4, + MXT_T100_TYPE_GLOVE = 5, + MXT_T100_TYPE_LARGE_TOUCH = 6, +}; + +/* Gen2 Active Stylus */ +#define MXT_T107_STYLUS_STYAUX 42 +#define MXT_T107_STYLUS_STYAUX_PRESSURE (1 << 0) +#define MXT_T107_STYLUS_STYAUX_PEAK (1 << 4) + +#define MXT_T107_STYLUS_HOVER (1 << 0) +#define MXT_T107_STYLUS_TIPSWITCH (1 << 1) +#define MXT_T107_STYLUS_BUTTON0 (1 << 2) +#define MXT_T107_STYLUS_BUTTON1 (1 << 3) + +#define MXT_TOUCH_MAJOR_DEFAULT 1 +#define MXT_PRESSURE_DEFAULT 1 + /* Delay times */ #define MXT_BACKUP_TIME 50 /* msec */ #define MXT_RESET_TIME 200 /* msec */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:198 @ struct t9_range { #define MXT_CRC_TIMEOUT 1000 /* msec */ #define MXT_FW_RESET_TIME 3000 /* msec */ #define MXT_FW_CHG_TIMEOUT 300 /* msec */ +#define MXT_WAKEUP_TIME 25 /* msec */ +#define MXT_REGULATOR_DELAY 150 /* msec */ +#define MXT_CHG_DELAY 100 /* msec */ +#define MXT_POWERON_DELAY 150 /* msec */ /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:223 @ struct t9_range { #define MXT_PIXELS_PER_MM 20 +#define DEBUG_MSG_MAX 200 + struct mxt_info { u8 family_id; u8 variant_id; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:250 @ struct mxt_data { char phys[64]; /* device physical location */ const struct mxt_platform_data *pdata; struct mxt_object *object_table; - struct mxt_info info; + struct mxt_info *info; + void *raw_info_block; unsigned int irq; unsigned int max_x; unsigned int max_y; bool in_bootloader; u16 mem_size; + u8 t100_aux_ampl; + u8 t100_aux_area; + u8 t100_aux_vect; + struct bin_attribute mem_access_attr; + bool debug_enabled; + bool debug_v2_enabled; + u8 *debug_msg_data; + u16 debug_msg_count; + struct bin_attribute debug_msg_attr; + struct mutex debug_msg_lock; u8 max_reportid; u32 config_crc; u32 info_crc; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:277 @ struct mxt_data { u8 last_message_count; u8 num_touchids; struct t7_config t7_cfg; + u8 num_stylusids; + unsigned long t15_keystatus; + u8 stylus_aux_pressure; + u8 stylus_aux_peak; + bool use_retrigen_workaround; + bool use_regulator; + struct regulator *reg_vdd; + struct regulator *reg_avdd; + char *fw_name; + char *cfg_name; /* Cached parameters from object table */ u16 T5_address; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:294 @ struct mxt_data { u8 T6_reportid; u16 T6_address; u16 T7_address; + u16 T71_address; u8 T9_reportid_min; u8 T9_reportid_max; + u8 T15_reportid_min; + u8 T15_reportid_max; + u16 T18_address; u8 T19_reportid; + u8 T42_reportid_min; + u8 T42_reportid_max; u16 T44_address; + u8 T48_reportid; + u8 T63_reportid_min; + u8 T63_reportid_max; + u8 T100_reportid_min; + u8 T100_reportid_max; + u16 T107_address; /* for fw update in bootloader */ struct completion bl_completion; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:319 @ struct mxt_data { /* for config update handling */ struct completion crc_completion; + + /* Indicates whether device is in suspend */ + bool suspended; + + /* Indicates whether device is updating configuration */ + bool updating_config; }; static size_t mxt_obj_size(const struct mxt_object *obj) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:364 @ static bool mxt_object_readable(unsigned case MXT_SPT_USERDATA_T38: case MXT_SPT_DIGITIZER_T43: case MXT_SPT_CTECONFIG_T46: + case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71: return true; default: return false; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:373 @ static bool mxt_object_readable(unsigned static void mxt_dump_message(struct mxt_data *data, u8 *message) { - dev_dbg(&data->client->dev, "message: %*ph\n", - data->T5_msg_size, message); + dev_dbg(&data->client->dev, "MXT MSG: %*ph\n", + data->T5_msg_size, message); +} + +static void mxt_debug_msg_enable(struct mxt_data *data) +{ + struct device *dev = &data->client->dev; + + if (data->debug_v2_enabled) + return; + + mutex_lock(&data->debug_msg_lock); + + data->debug_msg_data = kcalloc(DEBUG_MSG_MAX, + data->T5_msg_size, GFP_KERNEL); + if (!data->debug_msg_data) + return; + + data->debug_v2_enabled = true; + mutex_unlock(&data->debug_msg_lock); + + dev_info(dev, "Enabled message output\n"); +} + +static void mxt_debug_msg_disable(struct mxt_data *data) +{ + struct device *dev = &data->client->dev; + + if (!data->debug_v2_enabled) + return; + + dev_info(dev, "disabling message output\n"); + data->debug_v2_enabled = false; + + mutex_lock(&data->debug_msg_lock); + kfree(data->debug_msg_data); + data->debug_msg_data = NULL; + data->debug_msg_count = 0; + mutex_unlock(&data->debug_msg_lock); + dev_info(dev, "Disabled message output\n"); +} + +static void mxt_debug_msg_add(struct mxt_data *data, u8 *msg) +{ + struct device *dev = &data->client->dev; + + mutex_lock(&data->debug_msg_lock); + + if (!data->debug_msg_data) { + dev_err(dev, "No buffer!\n"); + return; + } + + if (data->debug_msg_count < DEBUG_MSG_MAX) { + memcpy(data->debug_msg_data + + data->debug_msg_count * data->T5_msg_size, + msg, + data->T5_msg_size); + data->debug_msg_count++; + } else { + dev_dbg(dev, "Discarding %u messages\n", data->debug_msg_count); + data->debug_msg_count = 0; + } + + mutex_unlock(&data->debug_msg_lock); + + sysfs_notify(&data->client->dev.kobj, NULL, "debug_notify"); +} + +static ssize_t mxt_debug_msg_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) +{ + return -EIO; +} + +static ssize_t mxt_debug_msg_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t bytes) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct mxt_data *data = dev_get_drvdata(dev); + int count; + size_t bytes_read; + + if (!data->debug_msg_data) { + dev_err(dev, "No buffer!\n"); + return 0; + } + + count = bytes / data->T5_msg_size; + + if (count > DEBUG_MSG_MAX) + count = DEBUG_MSG_MAX; + + mutex_lock(&data->debug_msg_lock); + + if (count > data->debug_msg_count) + count = data->debug_msg_count; + + bytes_read = count * data->T5_msg_size; + + memcpy(buf, data->debug_msg_data, bytes_read); + data->debug_msg_count = 0; + + mutex_unlock(&data->debug_msg_lock); + + return bytes_read; +} + +static int mxt_debug_msg_init(struct mxt_data *data) +{ + sysfs_bin_attr_init(&data->debug_msg_attr); + data->debug_msg_attr.attr.name = "debug_msg"; + data->debug_msg_attr.attr.mode = 0666; + data->debug_msg_attr.read = mxt_debug_msg_read; + data->debug_msg_attr.write = mxt_debug_msg_write; + data->debug_msg_attr.size = data->T5_msg_size * DEBUG_MSG_MAX; + + if (sysfs_create_bin_file(&data->client->dev.kobj, + &data->debug_msg_attr) < 0) { + dev_err(&data->client->dev, "Failed to create %s\n", + data->debug_msg_attr.attr.name); + return -EINVAL; + } + + return 0; +} + +static void mxt_debug_msg_remove(struct mxt_data *data) +{ + if (data->debug_msg_attr.attr.name) + sysfs_remove_bin_file(&data->client->dev.kobj, + &data->debug_msg_attr); } static int mxt_wait_for_completion(struct mxt_data *data, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:577 @ static int mxt_lookup_bootloader_address { u8 appmode = data->client->addr; u8 bootloader; + u8 family_id = data->info ? data->info->family_id : 0; switch (appmode) { case 0x4a: case 0x4b: /* Chips after 1664S use different scheme */ - if (retry || data->info.family_id >= 0xa2) { + if (retry || family_id >= 0xa2) { bootloader = appmode - 0x24; break; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:740 @ static int __mxt_read_reg(struct i2c_cli struct i2c_msg xfer[2]; u8 buf[2]; int ret; + bool retry = false; buf[0] = reg & 0xff; buf[1] = (reg >> 8) & 0xff; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:757 @ static int __mxt_read_reg(struct i2c_cli xfer[1].len = len; xfer[1].buf = val; - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret == 2) { - ret = 0; - } else { - if (ret >= 0) - ret = -EIO; - dev_err(&client->dev, "%s: i2c transfer failed (%d)\n", - __func__, ret); +retry_read: + ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret != ARRAY_SIZE(xfer)) { + if (!retry) { + dev_dbg(&client->dev, "%s: i2c retry\n", __func__); + msleep(MXT_WAKEUP_TIME); + retry = true; + goto retry_read; + } else { + dev_err(&client->dev, "%s: i2c transfer failed (%d)\n", + __func__, ret); + return -EIO; + } } - return ret; + return 0; } static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:781 @ static int __mxt_write_reg(struct i2c_cl u8 *buf; size_t count; int ret; + bool retry = false; count = len + 2; buf = kmalloc(count, GFP_KERNEL); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:792 @ static int __mxt_write_reg(struct i2c_cl buf[1] = (reg >> 8) & 0xff; memcpy(&buf[2], val, len); +retry_write: ret = i2c_master_send(client, buf, count); - if (ret == count) { - ret = 0; - } else { - if (ret >= 0) + if (ret != count) { + if (!retry) { + dev_dbg(&client->dev, "%s: i2c retry\n", __func__); + msleep(MXT_WAKEUP_TIME); + retry = true; + goto retry_write; + } else { + dev_err(&client->dev, "%s: i2c send failed (%d)\n", + __func__, ret); ret = -EIO; - dev_err(&client->dev, "%s: i2c send failed (%d)\n", - __func__, ret); + } + } else { + ret = 0; } kfree(buf); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:824 @ mxt_get_object(struct mxt_data *data, u8 struct mxt_object *object; int i; - for (i = 0; i < data->info.object_num; i++) { + for (i = 0; i < data->info->object_num; i++) { object = data->object_table + i; if (object->type == type) return object; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:840 @ static void mxt_proc_t6_messages(struct u8 status = msg[1]; u32 crc = msg[2] | (msg[3] << 8) | (msg[4] << 16); - complete(&data->crc_completion); - if (crc != data->config_crc) { data->config_crc = crc; dev_dbg(dev, "T6 Config Checksum: 0x%06X\n", crc); } + complete(&data->crc_completion); + /* Detect reset */ if (status & MXT_T6_STATUS_RESET) complete(&data->reset_completion); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:885 @ static void mxt_input_button(struct mxt_ static void mxt_input_sync(struct mxt_data *data) { - input_mt_report_pointer_emulation(data->input_dev, - data->pdata->t19_num_keys); - input_sync(data->input_dev); + if (data->input_dev) { + input_mt_report_pointer_emulation(data->input_dev, + data->pdata->t19_num_keys); + input_sync(data->input_dev); + } } static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:902 @ static void mxt_proc_t9_message(struct m int y; int area; int amplitude; + u8 vector; + int tool; id = message[0] - data->T9_reportid_min; status = message[1]; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:917 @ static void mxt_proc_t9_message(struct m y >>= 2; area = message[5]; + amplitude = message[6]; + vector = message[7]; dev_dbg(dev, - "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n", + "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u vector: %02X\n", id, (status & MXT_T9_DETECT) ? 'D' : '.', (status & MXT_T9_PRESS) ? 'P' : '.', @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:932 @ static void mxt_proc_t9_message(struct m (status & MXT_T9_AMP) ? 'A' : '.', (status & MXT_T9_SUPPRESS) ? 'S' : '.', (status & MXT_T9_UNGRIP) ? 'U' : '.', - x, y, area, amplitude); + x, y, area, amplitude, vector); input_mt_slot(input_dev, id); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:948 @ static void mxt_proc_t9_message(struct m mxt_input_sync(data); } + /* A size of zero indicates touch is from a linked T47 Stylus */ + if (area == 0) { + area = MXT_TOUCH_MAJOR_DEFAULT; + tool = MT_TOOL_PEN; + } else { + tool = MT_TOOL_FINGER; + } + /* Touch active */ - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1); + input_mt_report_slot_state(input_dev, tool, 1); input_report_abs(input_dev, ABS_MT_POSITION_X, x); input_report_abs(input_dev, ABS_MT_POSITION_Y, y); input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude); input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); + input_report_abs(input_dev, ABS_MT_ORIENTATION, vector); } else { /* Touch no longer active, close out slot */ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:971 @ static void mxt_proc_t9_message(struct m data->update_input = true; } +static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) +{ + struct device *dev = &data->client->dev; + struct input_dev *input_dev = data->input_dev; + int id; + u8 status; + u8 type; + int x; + int y; + int tool; + u8 major = 0; + u8 pressure = 0; + u8 orientation = 0; + bool active = false; + bool hover = false; + bool eraser = false; + bool barrel = false; + + id = message[0] - data->T100_reportid_min - 2; + + /* ignore SCRSTATUS events */ + if (id < 0) + return; + + status = message[1]; + x = (message[3] << 8) | message[2]; + y = (message[5] << 8) | message[4]; + + if (status & MXT_T100_DETECT) { + type = (status & MXT_T100_TYPE_MASK) >> 4; + + switch (type) { + case MXT_T100_TYPE_HOVERING_FINGER: + hover = true; + /* fall through */ + case MXT_T100_TYPE_FINGER: + case MXT_T100_TYPE_GLOVE: + active = true; + tool = MT_TOOL_FINGER; + + if (data->t100_aux_area) + major = message[data->t100_aux_area]; + if (data->t100_aux_ampl) + pressure = message[data->t100_aux_ampl]; + if (data->t100_aux_vect) + orientation = message[data->t100_aux_vect]; + + break; + + case MXT_T100_TYPE_PASSIVE_STYLUS: + active = true; + tool = MT_TOOL_PEN; + + /* Passive stylus is reported with size zero so + * hardcode */ + major = MXT_TOUCH_MAJOR_DEFAULT; + + if (data->t100_aux_ampl) + pressure = message[data->t100_aux_ampl]; + + break; + + case MXT_T100_TYPE_ACTIVE_STYLUS: + /* stylus in range, but position unavailable */ + if (!(message[6] & MXT_T107_STYLUS_HOVER)) + break; + + active = true; + tool = MT_TOOL_PEN; + major = MXT_TOUCH_MAJOR_DEFAULT; + eraser = message[6] & MXT_T107_STYLUS_BUTTON0; + barrel = message[6] & MXT_T107_STYLUS_BUTTON1; + + if (!(message[6] & MXT_T107_STYLUS_TIPSWITCH)) + hover = true; + else if (data->stylus_aux_pressure) + pressure = message[data->stylus_aux_pressure]; + + break; + + case MXT_T100_TYPE_LARGE_TOUCH: + /* Ignore suppressed touch */ + break; + + default: + dev_dbg(dev, "Unexpected T100 type\n"); + return; + } + } + + if (hover) { + pressure = 0; + major = 0; + } else if (active) { + /* + * Values reported should be non-zero if tool is touching the + * device + */ + if (pressure == 0) + pressure = MXT_PRESSURE_DEFAULT; + + if (major == 0) + major = MXT_TOUCH_MAJOR_DEFAULT; + } + + input_mt_slot(input_dev, id); + + if (active) { + dev_dbg(dev, "[%u] type:%u x:%u y:%u a:%02X p:%02X v:%02X\n", + id, type, x, y, major, pressure, orientation); + + input_mt_report_slot_state(input_dev, tool, 1); + input_report_abs(input_dev, ABS_MT_POSITION_X, x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, major); + input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); + input_report_abs(input_dev, ABS_MT_ORIENTATION, orientation); + + input_report_key(input_dev, BTN_STYLUS, eraser); + input_report_key(input_dev, BTN_STYLUS2, barrel); + } else { + dev_dbg(dev, "[%u] release\n", id); + + /* close out slot */ + input_mt_report_slot_state(input_dev, 0, 0); + } + + data->update_input = true; +} + +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *msg) +{ + struct input_dev *input_dev = data->input_dev; + struct device *dev = &data->client->dev; + int key; + bool curr_state, new_state; + bool sync = false; + unsigned long keystates = le32_to_cpu(msg[2]); + + for (key = 0; key < data->pdata->t15_num_keys; key++) { + curr_state = test_bit(key, &data->t15_keystatus); + new_state = test_bit(key, &keystates); + + if (!curr_state && new_state) { + dev_dbg(dev, "T15 key press: %u\n", key); + __set_bit(key, &data->t15_keystatus); + input_event(input_dev, EV_KEY, + data->pdata->t15_keymap[key], 1); + sync = true; + } else if (curr_state && !new_state) { + dev_dbg(dev, "T15 key release: %u\n", key); + __clear_bit(key, &data->t15_keystatus); + input_event(input_dev, EV_KEY, + data->pdata->t15_keymap[key], 0); + sync = true; + } + } + + if (sync) + input_sync(input_dev); +} + +static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = &data->client->dev; + u8 status = msg[1]; + + if (status & MXT_T42_MSG_TCHSUP) + dev_info(dev, "T42 suppress\n"); + else + dev_info(dev, "T42 normal\n"); +} + +static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = &data->client->dev; + u8 status, state; + + status = msg[1]; + state = msg[4]; + + dev_dbg(dev, "T48 state %d status %02X %s%s%s%s%s\n", state, status, + status & 0x01 ? "FREQCHG " : "", + status & 0x02 ? "APXCHG " : "", + status & 0x04 ? "ALGOERR " : "", + status & 0x10 ? "STATCHG " : "", + status & 0x20 ? "NLVLCHG " : ""); + + return 0; +} + +static void mxt_proc_t63_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = &data->client->dev; + struct input_dev *input_dev = data->input_dev; + u8 id; + u16 x, y; + u8 pressure; + + /* stylus slots come after touch slots */ + id = data->num_touchids + (msg[0] - data->T63_reportid_min); + + if (id < 0 || id > (data->num_touchids + data->num_stylusids)) { + dev_err(dev, "invalid stylus id %d, max slot is %d\n", + id, data->num_stylusids); + return; + } + + x = msg[3] | (msg[4] << 8); + y = msg[5] | (msg[6] << 8); + pressure = msg[7] & MXT_T63_STYLUS_PRESSURE_MASK; + + dev_dbg(dev, + "[%d] %c%c%c%c x: %d y: %d pressure: %d stylus:%c%c%c%c\n", + id, + msg[1] & MXT_T63_STYLUS_SUPPRESS ? 'S' : '.', + msg[1] & MXT_T63_STYLUS_MOVE ? 'M' : '.', + msg[1] & MXT_T63_STYLUS_RELEASE ? 'R' : '.', + msg[1] & MXT_T63_STYLUS_PRESS ? 'P' : '.', + x, y, pressure, + msg[2] & MXT_T63_STYLUS_BARREL ? 'B' : '.', + msg[2] & MXT_T63_STYLUS_ERASER ? 'E' : '.', + msg[2] & MXT_T63_STYLUS_TIP ? 'T' : '.', + msg[2] & MXT_T63_STYLUS_DETECT ? 'D' : '.'); + + input_mt_slot(input_dev, id); + + if (msg[2] & MXT_T63_STYLUS_DETECT) { + input_mt_report_slot_state(input_dev, MT_TOOL_PEN, 1); + input_report_abs(input_dev, ABS_MT_POSITION_X, x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); + } else { + input_mt_report_slot_state(input_dev, MT_TOOL_PEN, 0); + } + + input_report_key(input_dev, BTN_STYLUS, + (msg[2] & MXT_T63_STYLUS_ERASER)); + input_report_key(input_dev, BTN_STYLUS2, + (msg[2] & MXT_T63_STYLUS_BARREL)); + + mxt_input_sync(data); +} + static int mxt_proc_message(struct mxt_data *data, u8 *message) { u8 report_id = message[0]; + bool dump = data->debug_enabled; if (report_id == MXT_RPTID_NOMSG) return 0; if (report_id == data->T6_reportid) { mxt_proc_t6_messages(data, message); - } else if (!data->input_dev) { + } else if (report_id >= data->T42_reportid_min + && report_id <= data->T42_reportid_max) { + mxt_proc_t42_messages(data, message); + } else if (report_id == data->T48_reportid) { + mxt_proc_t48_messages(data, message); + } else if (!data->input_dev || data->suspended) { /* - * Do not report events if input device - * is not yet registered. + * Do not report events if input device is not + * yet registered or returning from suspend */ mxt_dump_message(data, message); } else if (report_id >= data->T9_reportid_min && report_id <= data->T9_reportid_max) { mxt_proc_t9_message(data, message); + } else if (report_id >= data->T100_reportid_min + && report_id <= data->T100_reportid_max) { + mxt_proc_t100_message(data, message); } else if (report_id == data->T19_reportid) { mxt_input_button(data, message); data->update_input = true; + } else if (report_id >= data->T63_reportid_min + && report_id <= data->T63_reportid_max) { + mxt_proc_t63_messages(data, message); + } else if (report_id >= data->T15_reportid_min + && report_id <= data->T15_reportid_max) { + mxt_proc_t15_messages(data, message); } else { - mxt_dump_message(data, message); + dump = true; } + if (dump) + mxt_dump_message(data, message); + + if (data->debug_v2_enabled) + mxt_debug_msg_add(data, message); + return 1; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1471 @ static int mxt_soft_reset(struct mxt_dat struct device *dev = &data->client->dev; int ret = 0; - dev_info(dev, "Resetting chip\n"); + dev_info(dev, "Resetting device\n"); + + disable_irq(data->irq); reinit_completion(&data->reset_completion); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1481 @ static int mxt_soft_reset(struct mxt_dat if (ret) return ret; + /* Ignore CHG line for 100ms after reset */ + msleep(100); + + enable_irq(data->irq); + ret = mxt_wait_for_completion(data, &data->reset_completion, MXT_RESET_TIMEOUT); if (ret) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1551 @ static u32 mxt_calculate_crc(u8 *base, o return crc; } +static int mxt_check_retrigen(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + int val; + + if (irq_get_trigger_type(data->irq) & IRQF_TRIGGER_LOW) + return 0; + + if (data->T18_address) { + error = __mxt_read_reg(client, + data->T18_address + MXT_COMMS_CTRL, + 1, &val); + if (error) + return error; + + if (val & MXT_COMMS_RETRIGEN) + return 0; + } + + dev_warn(&client->dev, "Enabling RETRIGEN workaround\n"); + data->use_retrigen_workaround = true; + return 0; +} + static int mxt_prepare_cfg_mem(struct mxt_data *data, const struct firmware *cfg, unsigned int data_pos, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1707 @ static int mxt_upload_cfg_mem(struct mxt return 0; } +static int mxt_init_t7_power_cfg(struct mxt_data *data); + /* * mxt_update_cfg - download configuration to chip * @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1740 @ static int mxt_update_cfg(struct mxt_dat u32 info_crc, config_crc, calculated_crc; u8 *config_mem; size_t config_mem_size; + u16 crc_start = 0; mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1764 @ static int mxt_update_cfg(struct mxt_dat data_pos += offset; } - if (cfg_info.family_id != data->info.family_id) { + if (cfg_info.family_id != data->info->family_id) { dev_err(dev, "Family ID mismatch!\n"); return -EINVAL; } - if (cfg_info.variant_id != data->info.variant_id) { + if (cfg_info.variant_id != data->info->variant_id) { dev_err(dev, "Variant ID mismatch!\n"); return -EINVAL; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1814 @ static int mxt_update_cfg(struct mxt_dat /* Malloc memory to store configuration */ cfg_start_ofs = MXT_OBJECT_START + - data->info.object_num * sizeof(struct mxt_object) + + data->info->object_num * sizeof(struct mxt_object) + MXT_INFO_CHECKSUM_SIZE; config_mem_size = data->mem_size - cfg_start_ofs; config_mem = kzalloc(config_mem_size, GFP_KERNEL); - if (!config_mem) { - dev_err(dev, "Failed to allocate memory\n"); + if (!config_mem) return -ENOMEM; - } ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs, config_mem, config_mem_size); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1827 @ static int mxt_update_cfg(struct mxt_dat goto release_mem; /* Calculate crc of the received configs (not the raw config file) */ - if (data->T7_address < cfg_start_ofs) { - dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n", - data->T7_address, cfg_start_ofs); - ret = 0; - goto release_mem; - } + if (data->T71_address) + crc_start = data->T71_address; + else if (data->T7_address) + crc_start = data->T7_address; + else + dev_warn(dev, "Could not find CRC start\n"); - calculated_crc = mxt_calculate_crc(config_mem, - data->T7_address - cfg_start_ofs, - config_mem_size); - - if (config_crc > 0 && config_crc != calculated_crc) - dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", - calculated_crc, config_crc); + if (crc_start > cfg_start_ofs) { + calculated_crc = mxt_calculate_crc(config_mem, + crc_start - cfg_start_ofs, + config_mem_size); + + if (config_crc > 0 && config_crc != calculated_crc) + dev_warn(dev, "Config CRC in file inconsistent, calculated=%06X, file=%06X\n", + calculated_crc, config_crc); + } ret = mxt_upload_cfg_mem(data, cfg_start_ofs, config_mem, config_mem_size); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1851 @ static int mxt_update_cfg(struct mxt_dat mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); + ret = mxt_check_retrigen(data); + if (ret) + goto release_mem; + ret = mxt_soft_reset(data); if (ret) goto release_mem; dev_info(dev, "Config successfully updated\n"); + /* T7 config may have changed */ + mxt_init_t7_power_cfg(data); + release_mem: kfree(config_mem); return ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1875 @ static int mxt_acquire_irq(struct mxt_da enable_irq(data->irq); - error = mxt_process_messages_until_invalid(data); - if (error) - return error; - - return 0; -} - -static int mxt_get_info(struct mxt_data *data) -{ - struct i2c_client *client = data->client; - struct mxt_info *info = &data->info; - int error; - - /* Read 7-byte info block starting at address 0 */ - error = __mxt_read_reg(client, MXT_INFO, sizeof(*info), info); - if (error) - return error; + if (data->use_retrigen_workaround) { + error = mxt_process_messages_until_invalid(data); + if (error) + return error; + } return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1894 @ static void mxt_free_input_device(struct static void mxt_free_object_table(struct mxt_data *data) { - kfree(data->object_table); + mxt_debug_msg_remove(data); + data->object_table = NULL; + data->info = NULL; + kfree(data->raw_info_block); + data->raw_info_block = NULL; kfree(data->msg_buf); data->msg_buf = NULL; data->T5_address = 0; data->T5_msg_size = 0; data->T6_reportid = 0; data->T7_address = 0; + data->T71_address = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + data->T15_reportid_min = 0; + data->T15_reportid_max = 0; + data->T18_address = 0; data->T19_reportid = 0; + data->T42_reportid_min = 0; + data->T42_reportid_max = 0; data->T44_address = 0; + data->T48_reportid = 0; + data->T63_reportid_min = 0; + data->T63_reportid_max = 0; + data->T100_reportid_min = 0; + data->T100_reportid_max = 0; data->max_reportid = 0; } -static int mxt_get_object_table(struct mxt_data *data) +static int mxt_parse_object_table(struct mxt_data *data, + struct mxt_object *object_table) { struct i2c_client *client = data->client; - size_t table_size; - struct mxt_object *object_table; - int error; int i; u8 reportid; u16 end_address; - table_size = data->info.object_num * sizeof(struct mxt_object); - object_table = kzalloc(table_size, GFP_KERNEL); - if (!object_table) { - dev_err(&data->client->dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - - error = __mxt_read_reg(client, MXT_OBJECT_START, table_size, - object_table); - if (error) { - kfree(object_table); - return error; - } - /* Valid Report IDs start counting from 1 */ reportid = 1; data->mem_size = 0; - for (i = 0; i < data->info.object_num; i++) { + for (i = 0; i < data->info->object_num; i++) { struct mxt_object *object = object_table + i; u8 min_id, max_id; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1959 @ static int mxt_get_object_table(struct m switch (object->type) { case MXT_GEN_MESSAGE_T5: - if (data->info.family_id == 0x80 && - data->info.version < 0x20) { + if (data->info->family_id == 0x80 && + data->info->version < 0x20) { /* * On mXT224 firmware versions prior to V2.0 * read and discard unused CRC byte otherwise @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1980 @ static int mxt_get_object_table(struct m case MXT_GEN_POWER_T7: data->T7_address = object->start_address; break; + case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71: + data->T71_address = object->start_address; + break; case MXT_TOUCH_MULTI_T9: + /* Only handle messages from first T9 instance */ data->T9_reportid_min = min_id; - data->T9_reportid_max = max_id; - data->num_touchids = object->num_report_ids - * mxt_obj_instances(object); + data->T9_reportid_max = min_id + + object->num_report_ids - 1; + data->num_touchids = object->num_report_ids; + break; + case MXT_TOUCH_KEYARRAY_T15: + data->T15_reportid_min = min_id; + data->T15_reportid_max = max_id; + break; + case MXT_SPT_COMMSCONFIG_T18: + data->T18_address = object->start_address; + break; + case MXT_PROCI_TOUCHSUPPRESSION_T42: + data->T42_reportid_min = min_id; + data->T42_reportid_max = max_id; break; case MXT_SPT_MESSAGECOUNT_T44: data->T44_address = object->start_address; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2007 @ static int mxt_get_object_table(struct m case MXT_SPT_GPIOPWM_T19: data->T19_reportid = min_id; break; - } - + case MXT_PROCG_NOISESUPPRESSION_T48: + data->T48_reportid = min_id; + break; + case MXT_PROCI_ACTIVE_STYLUS_T63: + /* Only handle messages from first T63 instance */ + data->T63_reportid_min = min_id; + data->T63_reportid_max = min_id; + data->num_stylusids = 1; + break; + case MXT_TOUCH_MULTITOUCHSCREEN_T100: + data->T100_reportid_min = min_id; + data->T100_reportid_max = max_id; + /* first two report IDs reserved */ + data->num_touchids = object->num_report_ids - 2; + break; + case MXT_PROCI_ACTIVESTYLUS_T107: + data->T107_address = object->start_address; + break; + } + end_address = object->start_address + mxt_obj_size(object) * mxt_obj_instances(object) - 1; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2040 @ static int mxt_get_object_table(struct m /* If T44 exists, T5 position has to be directly after */ if (data->T44_address && (data->T5_address != data->T44_address + 1)) { dev_err(&client->dev, "Invalid T44 position\n"); - error = -EINVAL; - goto free_object_table; + return -EINVAL; } data->msg_buf = kcalloc(data->max_reportid, data->T5_msg_size, GFP_KERNEL); - if (!data->msg_buf) { - dev_err(&client->dev, "Failed to allocate message buffer\n"); + if (!data->msg_buf) + return -ENOMEM; + + return 0; +} + +static int mxt_read_info_block(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + size_t size; + void *id_buf, *buf; + uint8_t num_objects; + u32 calculated_crc; + u8 *crc_ptr; + + /* If info block already allocated, free it */ + if (data->raw_info_block != NULL) + mxt_free_object_table(data); + + /* Read 7-byte ID information block starting at address 0 */ + size = sizeof(struct mxt_info); + id_buf = kzalloc(size, GFP_KERNEL); + if (!id_buf) + return -ENOMEM; + + error = __mxt_read_reg(client, 0, size, id_buf); + if (error) { + kfree(id_buf); + return error; + } + + /* Resize buffer to give space for rest of info block */ + num_objects = ((struct mxt_info *)id_buf)->object_num; + size += (num_objects * sizeof(struct mxt_object)) + + MXT_INFO_CHECKSUM_SIZE; + + buf = krealloc(id_buf, size, GFP_KERNEL); + if (!buf) { error = -ENOMEM; - goto free_object_table; + goto err_free_mem; } - data->object_table = object_table; + /* Read rest of info block */ + error = __mxt_read_reg(client, MXT_OBJECT_START, + size - MXT_OBJECT_START, + buf + MXT_OBJECT_START); + if (error) + goto err_free_mem; + + /* Extract & calculate checksum */ + crc_ptr = buf + size - MXT_INFO_CHECKSUM_SIZE; + data->info_crc = crc_ptr[0] | (crc_ptr[1] << 8) | (crc_ptr[2] << 16); + + calculated_crc = mxt_calculate_crc(buf, 0, + size - MXT_INFO_CHECKSUM_SIZE); + + /* + * CRC mismatch can be caused by data corruption due to I2C comms + * issue or else device is not using Object Based Protocol (eg i2c-hid) + */ + if ((data->info_crc == 0) || (data->info_crc != calculated_crc)) { + dev_err(&client->dev, + "Info Block CRC error calculated=0x%06X read=0x%06X\n", + calculated_crc, data->info_crc); + error = -EIO; + goto err_free_mem; + } + + data->raw_info_block = buf; + data->info = (struct mxt_info *)buf; + + dev_info(&client->dev, + "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", + data->info->family_id, data->info->variant_id, + data->info->version >> 4, data->info->version & 0xf, + data->info->build, data->info->object_num); + + /* Parse object table information */ + error = mxt_parse_object_table(data, buf + MXT_OBJECT_START); + if (error) { + dev_err(&client->dev, "Error %d parsing object table\n", error); + mxt_free_object_table(data); + return error; + } + + data->object_table = (struct mxt_object *)(buf + MXT_OBJECT_START); return 0; -free_object_table: - mxt_free_object_table(data); +err_free_mem: + kfree(buf); return error; } +static void mxt_regulator_enable(struct mxt_data *data) +{ + int error; + + gpio_set_value(data->pdata->gpio_reset, 0); + + error = regulator_enable(data->reg_vdd); + if (error) + return; + + error = regulator_enable(data->reg_avdd); + if (error) + return; + + msleep(MXT_REGULATOR_DELAY); + gpio_set_value(data->pdata->gpio_reset, 1); + msleep(MXT_CHG_DELAY); + +retry_wait: + reinit_completion(&data->bl_completion); + data->in_bootloader = true; + error = mxt_wait_for_completion(data, &data->bl_completion, + MXT_POWERON_DELAY); + if (error == -EINTR) + goto retry_wait; + + data->in_bootloader = false; +} + +static void mxt_regulator_disable(struct mxt_data *data) +{ + regulator_disable(data->reg_vdd); + regulator_disable(data->reg_avdd); +} + +static void mxt_probe_regulators(struct mxt_data *data) +{ + struct device *dev = &data->client->dev; + int error; + + /* + * According to maXTouch power sequencing specification, RESET line + * must be kept low until some time after regulators come up to + * voltage + */ + if (!gpio_is_valid(data->pdata->gpio_reset)) { + dev_dbg(dev, "Must have reset GPIO to use regulator support\n"); + goto fail; + } + + data->reg_vdd = regulator_get(dev, "vdd"); + if (IS_ERR(data->reg_vdd)) { + error = PTR_ERR(data->reg_vdd); + dev_err(dev, "Error %d getting vdd regulator\n", error); + goto fail; + } + + data->reg_avdd = regulator_get(dev, "avdd"); + if (IS_ERR(data->reg_avdd)) { + error = PTR_ERR(data->reg_avdd); + dev_err(dev, "Error %d getting avdd regulator\n", error); + goto fail_release; + } + + data->use_regulator = true; + mxt_regulator_enable(data); + + dev_dbg(dev, "Initialised regulators\n"); + return; + +fail_release: + regulator_put(data->reg_vdd); +fail: + data->reg_vdd = NULL; + data->reg_avdd = NULL; + data->use_regulator = false; +} + static int mxt_read_t9_resolution(struct mxt_data *data) { struct i2c_client *client = data->client; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2284 @ static int mxt_initialize_t9_input_devic dev_warn(dev, "Failed to initialize T9 resolution\n"); input_dev = input_allocate_device(); - if (!input_dev) { - dev_err(dev, "Failed to allocate memory\n"); + if (!input_dev) return -ENOMEM; - } input_dev->name = "Atmel maXTouch Touchscreen"; input_dev->phys = data->phys; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2316 @ static int mxt_initialize_t9_input_devic MXT_PIXELS_PER_MM); input_dev->name = "Atmel maXTouch Touchpad"; + } else { + mt_flags |= INPUT_MT_DIRECT; } /* For single touch */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2329 @ static int mxt_initialize_t9_input_devic 0, 255, 0, 0); /* For multi touch */ - num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; + num_mt_slots = data->num_touchids + data->num_stylusids; error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); if (error) { dev_err(dev, "Error %d initialising slots\n", error); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2344 @ static int mxt_initialize_t9_input_devic 0, data->max_y, 0, 0); input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_MT_ORIENTATION, + 0, 255, 0, 0); + + /* For T63 active stylus */ + if (data->T63_reportid_min) { + input_set_capability(input_dev, EV_KEY, BTN_STYLUS); + input_set_capability(input_dev, EV_KEY, BTN_STYLUS2); + input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, + 0, MT_TOOL_MAX, 0, 0); + } + + /* For T15 key array */ + if (data->T15_reportid_min) { + data->t15_keystatus = 0; + + for (i = 0; i < data->pdata->t15_num_keys; i++) + input_set_capability(input_dev, EV_KEY, + data->pdata->t15_keymap[i]); + } + + input_set_drvdata(input_dev, data); + + error = input_register_device(input_dev); + if (error) { + dev_err(dev, "Error %d registering input device\n", error); + goto err_free_mem; + } + + data->input_dev = input_dev; + + return 0; + +err_free_mem: + input_free_device(input_dev); + return error; +} + +static int mxt_read_t107_stylus_config(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + struct mxt_object *object; + u8 styaux; + int aux; + + object = mxt_get_object(data, MXT_PROCI_ACTIVESTYLUS_T107); + if (!object) + return 0; + + error = __mxt_read_reg(client, + object->start_address + MXT_T107_STYLUS_STYAUX, + 1, &styaux); + if (error) + return error; + + /* map aux bits */ + aux = 7; + + if (styaux & MXT_T107_STYLUS_STYAUX_PRESSURE) + data->stylus_aux_pressure = aux++; + + if (styaux & MXT_T107_STYLUS_STYAUX_PEAK) + data->stylus_aux_peak = aux++; + + dev_dbg(&client->dev, + "Enabling T107 active stylus, aux map pressure:%u peak:%u\n", + data->stylus_aux_pressure, data->stylus_aux_peak); + + return 0; +} + +static int mxt_read_t100_config(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + struct mxt_object *object; + u16 range_x, range_y; + u8 cfg, tchaux; + u8 aux; + + object = mxt_get_object(data, MXT_TOUCH_MULTITOUCHSCREEN_T100); + if (!object) + return -EINVAL; + + error = __mxt_read_reg(client, + object->start_address + MXT_T100_XRANGE, + sizeof(range_x), &range_x); + if (error) + return error; + + le16_to_cpus(&range_x); + + error = __mxt_read_reg(client, + object->start_address + MXT_T100_YRANGE, + sizeof(range_y), &range_y); + if (error) + return error; + + le16_to_cpus(&range_y); + + error = __mxt_read_reg(client, + object->start_address + MXT_T100_CFG1, + 1, &cfg); + if (error) + return error; + + error = __mxt_read_reg(client, + object->start_address + MXT_T100_TCHAUX, + 1, &tchaux); + if (error) + return error; + + /* Handle default values */ + if (range_x == 0) + range_x = 1023; + + if (range_y == 0) + range_y = 1023; + + if (cfg & MXT_T100_CFG_SWITCHXY) { + data->max_x = range_y; + data->max_y = range_x; + } else { + data->max_x = range_x; + data->max_y = range_y; + } + + /* allocate aux bytes */ + aux = 6; + + if (tchaux & MXT_T100_TCHAUX_VECT) + data->t100_aux_vect = aux++; + + if (tchaux & MXT_T100_TCHAUX_AMPL) + data->t100_aux_ampl = aux++; + + if (tchaux & MXT_T100_TCHAUX_AREA) + data->t100_aux_area = aux++; + + dev_dbg(&client->dev, + "T100 aux mappings vect:%u ampl:%u area:%u\n", + data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area); + + dev_info(&client->dev, + "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y); + + return 0; +} + +static int mxt_initialize_t100_input_device(struct mxt_data *data) +{ + struct device *dev = &data->client->dev; + struct input_dev *input_dev; + int error; + + error = mxt_read_t100_config(data); + if (error) { + dev_err(dev, "Failed to read T100 config\n"); + return error; + } + + mxt_read_t107_stylus_config(data); + + input_dev = input_allocate_device(); + if (!data || !input_dev) + return -ENOMEM; + + if (data->pdata->input_name) + input_dev->name = data->pdata->input_name; + else + input_dev->name = "atmel_mxt_ts T100 touchscreen"; + + input_dev->phys = data->phys; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = &data->client->dev; + input_dev->open = mxt_input_open; + input_dev->close = mxt_input_close; + + set_bit(EV_ABS, input_dev->evbit); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); + + /* For single touch */ + input_set_abs_params(input_dev, ABS_X, + 0, data->max_x, 0, 0); + input_set_abs_params(input_dev, ABS_Y, + 0, data->max_y, 0, 0); + + if (data->t100_aux_ampl) + input_set_abs_params(input_dev, ABS_PRESSURE, + 0, 255, 0, 0); + + /* For multi touch */ + error = input_mt_init_slots(input_dev, data->num_touchids, + INPUT_MT_DIRECT); + if (error) { + dev_err(dev, "Error %d initialising slots\n", error); + goto err_free_mem; + } + + input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, + 0, data->max_x, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, + 0, data->max_y, 0, 0); + + if (data->T107_address) { + input_set_capability(input_dev, EV_KEY, BTN_STYLUS); + input_set_capability(input_dev, EV_KEY, BTN_STYLUS2); + } + + if (data->t100_aux_area) + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, MXT_MAX_AREA, 0, 0); + + if (data->t100_aux_ampl | data->stylus_aux_pressure) + input_set_abs_params(input_dev, ABS_MT_PRESSURE, + 0, 255, 0, 0); + + if (data->t100_aux_vect) + input_set_abs_params(input_dev, ABS_MT_ORIENTATION, + 0, 255, 0, 0); input_set_drvdata(input_dev, data); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2599 @ static int mxt_initialize(struct mxt_dat int error; while (1) { - error = mxt_get_info(data); + error = mxt_read_info_block(data); if (!error) break; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2630 @ static int mxt_initialize(struct mxt_dat msleep(MXT_FW_RESET_TIME); } - /* Get object table information */ - error = mxt_get_object_table(data); - if (error) { - dev_err(&client->dev, "Error %d reading object table\n", error); - return error; - } + error = mxt_check_retrigen(data); + if (error) + goto err_free_object_table; error = mxt_acquire_irq(data); if (error) goto err_free_object_table; - error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, - &client->dev, GFP_KERNEL, data, - mxt_config_cb); - if (error) { - dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", - error); + error = mxt_debug_msg_init(data); + if (error) goto err_free_object_table; + + if (data->cfg_name) { + error = request_firmware_nowait(THIS_MODULE, true, + data->cfg_name, &data->client->dev, + GFP_KERNEL, data, mxt_config_cb); + if (error) { + dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", + error); + goto err_free_object_table; + } + } else { + error = mxt_configure_objects(data, NULL); + if (error) + goto err_free_object_table; } return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2722 @ static int mxt_configure_objects(struct const struct firmware *cfg) { struct device *dev = &data->client->dev; - struct mxt_info *info = &data->info; int error; + error = mxt_init_t7_power_cfg(data); + if (error) { + dev_err(dev, "Failed to initialize power cfg\n"); + goto err_free_object_table; + } + if (cfg) { error = mxt_update_cfg(data, cfg); if (error) dev_warn(dev, "Error %d updating config\n", error); } - error = mxt_init_t7_power_cfg(data); - if (error) { - dev_err(dev, "Failed to initialize power cfg\n"); - return error; + if (data->T9_reportid_min) { + error = mxt_initialize_t9_input_device(data); + if (error) + goto err_free_object_table; + } else if (data->T100_reportid_min) { + error = mxt_initialize_t100_input_device(data); + if (error) + goto err_free_object_table; + } else { + dev_warn(dev, "No touch object detected\n"); } - error = mxt_initialize_t9_input_device(data); - if (error) - return error; + return 0; - dev_info(dev, - "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", - info->family_id, info->variant_id, info->version >> 4, - info->version & 0xf, info->build, info->object_num); +err_free_object_table: + mxt_free_object_table(data); + return error; +} - return 0; +/* Configuration crc check sum is returned as hex xxxxxx */ +static ssize_t mxt_config_csum_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_crc); } /* Firmware Version is returned as Major.Minor.Build */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2769 @ static ssize_t mxt_fw_version_show(struc struct device_attribute *attr, char *buf) { struct mxt_data *data = dev_get_drvdata(dev); - struct mxt_info *info = &data->info; + + if (!data->object_table) + return -EINVAL; + return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", - info->version >> 4, info->version & 0xf, info->build); + data->info->version >> 4, data->info->version & 0xf, + data->info->build); } /* Hardware Version is returned as FamilyID.VariantID */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2783 @ static ssize_t mxt_hw_version_show(struc struct device_attribute *attr, char *buf) { struct mxt_data *data = dev_get_drvdata(dev); - struct mxt_info *info = &data->info; + + if (!data->object_table) + return -EINVAL; + return scnprintf(buf, PAGE_SIZE, "%u.%u\n", - info->family_id, info->variant_id); + data->info->family_id, data->info->variant_id); } static ssize_t mxt_show_instance(char *buf, int count, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2819 @ static ssize_t mxt_object_show(struct de int error; u8 *obuf; + if (!data->object_table) + return -EINVAL; + /* Pre-allocate buffer large enough to hold max sized object. */ obuf = kmalloc(256, GFP_KERNEL); if (!obuf) return -ENOMEM; error = 0; - for (i = 0; i < data->info.object_num; i++) { + for (i = 0; i < data->info->object_num; i++) { object = data->object_table + i; if (!mxt_object_readable(object->type)) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2878 @ static int mxt_check_firmware_format(str return -EINVAL; } -static int mxt_load_fw(struct device *dev, const char *fn) +static int mxt_load_fw(struct device *dev) { struct mxt_data *data = dev_get_drvdata(dev); const struct firmware *fw = NULL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2888 @ static int mxt_load_fw(struct device *de unsigned int frame = 0; int ret; - ret = request_firmware(&fw, fn, dev); + ret = request_firmware(&fw, data->fw_name, dev); if (ret) { - dev_err(dev, "Unable to open firmware %s\n", fn); + dev_err(dev, "Unable to open firmware %s\n", data->fw_name); return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2899 @ static int mxt_load_fw(struct device *de if (ret) goto release_firmware; + if (data->suspended) { + if (data->use_regulator) + mxt_regulator_enable(data); + + enable_irq(data->irq); + data->suspended = false; + } + if (!data->in_bootloader) { /* Change to the bootloader mode */ data->in_bootloader = true; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3007 @ release_firmware: return ret; } +static int mxt_update_file_name(struct device *dev, char **file_name, + const char *buf, size_t count) +{ + char *file_name_tmp; + + /* Simple sanity check */ + if (count > 64) { + dev_warn(dev, "File name too long\n"); + return -EINVAL; + } + + file_name_tmp = krealloc(*file_name, count + 1, GFP_KERNEL); + if (!file_name_tmp) + return -ENOMEM; + + *file_name = file_name_tmp; + memcpy(*file_name, buf, count); + + /* Echo into the sysfs entry may append newline at the end of buf */ + if (buf[count - 1] == '\n') + (*file_name)[count - 1] = '\0'; + else + (*file_name)[count] = '\0'; + + return 0; +} + static ssize_t mxt_update_fw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3041 @ static ssize_t mxt_update_fw_store(struc struct mxt_data *data = dev_get_drvdata(dev); int error; - error = mxt_load_fw(dev, MXT_FW_NAME); + error = mxt_update_file_name(dev, &data->fw_name, buf, count); + if (error) + return error; + + error = mxt_load_fw(dev); if (error) { dev_err(dev, "The firmware update failed(%d)\n", error); count = error; } else { dev_info(dev, "The firmware update succeeded\n"); + data->suspended = false; + error = mxt_initialize(data); if (error) return error; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3062 @ static ssize_t mxt_update_fw_store(struc return count; } +static ssize_t mxt_update_cfg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + const struct firmware *cfg; + int ret; + + if (data->in_bootloader) { + dev_err(dev, "Not in appmode\n"); + return -EINVAL; + } + + ret = mxt_update_file_name(dev, &data->cfg_name, buf, count); + if (ret) + return ret; + + ret = request_firmware(&cfg, data->cfg_name, dev); + if (ret < 0) { + dev_err(dev, "Failure to request config file %s\n", + data->cfg_name); + ret = -ENOENT; + goto out; + } + + data->updating_config = true; + + mxt_free_input_device(data); + + if (data->suspended) { + if (data->use_regulator) { + enable_irq(data->irq); + mxt_regulator_enable(data); + } else { + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + mxt_acquire_irq(data); + } + + data->suspended = false; + } + + ret = mxt_configure_objects(data, cfg); + if (ret) + goto release; + + ret = count; + +release: + release_firmware(cfg); +out: + data->updating_config = false; + return ret; +} + +static ssize_t mxt_debug_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + char c; + + c = data->debug_enabled ? '1' : '0'; + return scnprintf(buf, PAGE_SIZE, "%c\n", c); +} + +static ssize_t mxt_debug_notify_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "0\n"); +} + +static ssize_t mxt_debug_v2_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + u8 i; + ssize_t ret; + + if (kstrtou8(buf, 0, &i) == 0 && i < 2) { + if (i == 1) + mxt_debug_msg_enable(data); + else + mxt_debug_msg_disable(data); + + ret = count; + } else { + dev_dbg(dev, "debug_enabled write error\n"); + ret = -EINVAL; + } + + return ret; +} + +static ssize_t mxt_debug_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + u8 i; + ssize_t ret; + + if (kstrtou8(buf, 0, &i) == 0 && i < 2) { + data->debug_enabled = (i == 1); + + dev_dbg(dev, "%s\n", i ? "debug enabled" : "debug disabled"); + ret = count; + } else { + dev_dbg(dev, "debug_enabled write error\n"); + ret = -EINVAL; + } + + return ret; +} + +static int mxt_check_mem_access_params(struct mxt_data *data, loff_t off, + size_t *count) +{ + if (off >= data->mem_size) + return -EIO; + + if (off + *count > data->mem_size) + *count = data->mem_size - off; + + if (*count > MXT_MAX_BLOCK_WRITE) + *count = MXT_MAX_BLOCK_WRITE; + + return 0; +} + +static ssize_t mxt_mem_access_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct mxt_data *data = dev_get_drvdata(dev); + int ret = 0; + + ret = mxt_check_mem_access_params(data, off, &count); + if (ret < 0) + return ret; + + if (count > 0) + ret = __mxt_read_reg(data->client, off, count, buf); + + return ret == 0 ? count : ret; +} + +static ssize_t mxt_mem_access_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct mxt_data *data = dev_get_drvdata(dev); + int ret = 0; + + ret = mxt_check_mem_access_params(data, off, &count); + if (ret < 0) + return ret; + + if (count > 0) + ret = __mxt_write_reg(data->client, off, count, buf); + + return ret == 0 ? count : ret; +} + static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL); static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store); +static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store); +static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL); +static DEVICE_ATTR(debug_enable, S_IWUSR | S_IRUSR, mxt_debug_enable_show, + mxt_debug_enable_store); +static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, NULL, + mxt_debug_v2_enable_store); +static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL); static struct attribute *mxt_attrs[] = { &dev_attr_fw_version.attr, &dev_attr_hw_version.attr, &dev_attr_object.attr, &dev_attr_update_fw.attr, + &dev_attr_update_cfg.attr, + &dev_attr_config_csum.attr, + &dev_attr_debug_enable.attr, + &dev_attr_debug_v2_enable.attr, + &dev_attr_debug_notify.attr, NULL }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3253 @ static const struct attribute_group mxt_ .attrs = mxt_attrs, }; +static void mxt_reset_slots(struct mxt_data *data) +{ + struct input_dev *input_dev = data->input_dev; + unsigned int num_mt_slots; + int id; + + if (!input_dev) + return; + + num_mt_slots = data->num_touchids + data->num_stylusids; + + for (id = 0; id < num_mt_slots; id++) { + input_mt_slot(input_dev, id); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); + } + + mxt_input_sync(data); +} + static void mxt_start(struct mxt_data *data) { - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + if (!data->suspended || data->in_bootloader) + return; + + if (data->use_regulator) { + enable_irq(data->irq); + + mxt_regulator_enable(data); + } else { + /* + * Discard any messages still in message buffer + * from before chip went to sleep + */ + mxt_process_messages_until_invalid(data); + + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + + /* Recalibrate since chip has been in deep sleep */ + mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + + mxt_acquire_irq(data); + } - /* Recalibrate since chip has been in deep sleep */ - mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + data->suspended = false; } static void mxt_stop(struct mxt_data *data) { - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + if (data->suspended || data->in_bootloader || data->updating_config) + return; + + disable_irq(data->irq); + + if (data->use_regulator) + mxt_regulator_disable(data); + else + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + + mxt_reset_slots(data); + data->suspended = true; } static int mxt_input_open(struct input_dev *dev) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3336 @ static struct mxt_platform_data *mxt_par { struct mxt_platform_data *pdata; u32 *keymap; - u32 keycode; - int proplen, i, ret; + int proplen, ret; if (!client->dev.of_node) return ERR_PTR(-ENODEV); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3345 @ static struct mxt_platform_data *mxt_par if (!pdata) return ERR_PTR(-ENOMEM); + /* reset gpio */ + pdata->gpio_reset = of_get_named_gpio_flags(client->dev.of_node, + "atmel,reset-gpio", 0, NULL); + + of_property_read_string(client->dev.of_node, "atmel,cfg_name", + &pdata->cfg_name); + + of_property_read_string(client->dev.of_node, "atmel,input_name", + &pdata->input_name); + if (of_find_property(client->dev.of_node, "linux,gpio-keymap", &proplen)) { pdata->t19_num_keys = proplen / sizeof(u32); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3365 @ static struct mxt_platform_data *mxt_par if (!keymap) return ERR_PTR(-ENOMEM); - for (i = 0; i < pdata->t19_num_keys; i++) { - ret = of_property_read_u32_index(client->dev.of_node, - "linux,gpio-keymap", i, &keycode); - if (ret) - keycode = KEY_RESERVED; - - keymap[i] = keycode; + ret = of_property_read_u32_array(client->dev.of_node, + "linux,gpio-keymap", keymap, pdata->t19_num_keys); + if (ret) { + dev_err(&client->dev, + "Unable to read device tree key codes: %d\n", + ret); + return NULL; } pdata->t19_keymap = keymap; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3382 @ static struct mxt_platform_data *mxt_par #else static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client) { - dev_dbg(&client->dev, "No platform data specified\n"); - return ERR_PTR(-EINVAL); + struct mxt_platform_data *pdata; + + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + /* Set default parameters */ + pdata->irqflags = IRQF_TRIGGER_FALLING; + + return pdata; } #endif @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3409 @ static int mxt_probe(struct i2c_client * } data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); - if (!data) { - dev_err(&client->dev, "Failed to allocate memory\n"); + if (!data) return -ENOMEM; - } snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", client->adapter->nr, client->addr); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3420 @ static int mxt_probe(struct i2c_client * data->irq = client->irq; i2c_set_clientdata(client, data); + if (data->pdata->cfg_name) + mxt_update_file_name(&data->client->dev, + &data->cfg_name, + data->pdata->cfg_name, + strlen(data->pdata->cfg_name)); + init_completion(&data->bl_completion); init_completion(&data->reset_completion); init_completion(&data->crc_completion); + mutex_init(&data->debug_msg_lock); error = request_threaded_irq(client->irq, NULL, mxt_interrupt, pdata->irqflags | IRQF_ONESHOT, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3439 @ static int mxt_probe(struct i2c_client * goto err_free_mem; } - disable_irq(client->irq); + mxt_probe_regulators(data); - error = mxt_initialize(data); - if (error) - goto err_free_irq; + disable_irq(data->irq); error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); if (error) { dev_err(&client->dev, "Failure %d creating sysfs group\n", error); - goto err_free_object; + goto err_free_irq; + } + + sysfs_bin_attr_init(&data->mem_access_attr); + data->mem_access_attr.attr.name = "mem_access"; + data->mem_access_attr.attr.mode = S_IRUGO | S_IWUSR; + data->mem_access_attr.read = mxt_mem_access_read; + data->mem_access_attr.write = mxt_mem_access_write; + data->mem_access_attr.size = data->mem_size; + + if (sysfs_create_bin_file(&client->dev.kobj, + &data->mem_access_attr) < 0) { + dev_err(&client->dev, "Failed to create %s\n", + data->mem_access_attr.attr.name); + goto err_remove_sysfs_group; + } + + error = mxt_initialize(data); + if (error) { + /* Wait and try a second time */ + msleep(MXT_RESET_TIME); + dev_warn(&client->dev, "Try a second time to init maxtouch\n"); + error = mxt_initialize(data); + if (error) + goto err_remove_mem_access; } return 0; -err_free_object: - mxt_free_input_device(data); - mxt_free_object_table(data); +err_remove_mem_access: + sysfs_remove_bin_file(&client->dev.kobj, &data->mem_access_attr); + data->mem_access_attr.attr.name = NULL; +err_remove_sysfs_group: + sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); err_free_irq: free_irq(client->irq, data); err_free_mem: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3492 @ static int mxt_remove(struct i2c_client { struct mxt_data *data = i2c_get_clientdata(client); + if (data->mem_access_attr.attr.name) + sysfs_remove_bin_file(&client->dev.kobj, + &data->mem_access_attr); + sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); free_irq(data->irq, data); + regulator_put(data->reg_avdd); + regulator_put(data->reg_vdd); mxt_free_input_device(data); mxt_free_object_table(data); kfree(data); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3507 @ static int mxt_remove(struct i2c_client return 0; } -#ifdef CONFIG_PM_SLEEP -static int mxt_suspend(struct device *dev) +static int __maybe_unused mxt_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3523 @ static int mxt_suspend(struct device *de return 0; } -static int mxt_resume(struct device *dev) +static int __maybe_unused mxt_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:3538 @ static int mxt_resume(struct device *dev return 0; } -#endif static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); Index: linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/irqchip/irq-atmel-aic.c +++ linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:212 @ static const struct irq_domain_ops aic_i .xlate = aic_irq_domain_xlate, }; -static void __init at91sam9_aic_irq_fixup(struct device_node *root) +static void __init at91rm9200_aic_irq_fixup(struct device_node *root) { aic_common_rtc_irq_fixup(root); } +static void __init at91sam9260_aic_irq_fixup(struct device_node *root) +{ + aic_common_rtt_irq_fixup(root); +} + +static void __init at91sam9g45_aic_irq_fixup(struct device_node *root) +{ + aic_common_rtc_irq_fixup(root); + aic_common_rtt_irq_fixup(root); +} + static const struct of_device_id __initdata aic_irq_fixups[] = { - { .compatible = "atmel,at91sam9g45", .data = at91sam9_aic_irq_fixup }, - { .compatible = "atmel,at91sam9n12", .data = at91sam9_aic_irq_fixup }, - { .compatible = "atmel,at91sam9rl", .data = at91sam9_aic_irq_fixup }, - { .compatible = "atmel,at91sam9x5", .data = at91sam9_aic_irq_fixup }, + { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup }, + { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup }, + { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup }, + { .compatible = "atmel,at91sam9rl", .data = at91sam9g45_aic_irq_fixup }, + { .compatible = "atmel,at91sam9x5", .data = at91rm9200_aic_irq_fixup }, + { .compatible = "atmel,at91sam9260", .data = at91sam9260_aic_irq_fixup }, + { .compatible = "atmel,at91sam9261", .data = at91sam9260_aic_irq_fixup }, + { .compatible = "atmel,at91sam9263", .data = at91sam9260_aic_irq_fixup }, + { .compatible = "atmel,at91sam9g20", .data = at91sam9260_aic_irq_fixup }, { /* sentinel */ }, }; Index: linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic-common.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/irqchip/irq-atmel-aic-common.c +++ linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic-common.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:170 @ void __init aic_common_rtc_irq_fixup(str iounmap(regs); } +#define AT91_RTT_MR 0x00 /* Real-time Mode Register */ +#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ +#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ + +void __init aic_common_rtt_irq_fixup(struct device_node *root) +{ + struct device_node *np; + void __iomem *regs; + + /* + * The at91sam9263 SoC has 2 instances of the RTT block, hence we + * iterate over the DT to find each occurrence. + */ + for_each_compatible_node(np, NULL, "atmel,at91sam9260-rtt") { + regs = of_iomap(np, 0); + if (!regs) + continue; + + writel(readl(regs + AT91_RTT_MR) & + ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN), + regs + AT91_RTT_MR); + + iounmap(regs); + } +} + void __init aic_common_irq_fixup(const struct of_device_id *matches) { struct device_node *root = of_find_node_by_path("/"); Index: linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic-common.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/irqchip/irq-atmel-aic-common.h +++ linux-3.18.13-rt10-r7s4/drivers/irqchip/irq-atmel-aic-common.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:37 @ struct irq_domain *__init aic_common_of_ void __init aic_common_rtc_irq_fixup(struct device_node *root); +void __init aic_common_rtt_irq_fixup(struct device_node *root); + void __init aic_common_irq_fixup(const struct of_device_id *matches); #endif /* __IRQ_ATMEL_AIC_COMMON_H */ Index: linux-3.18.13-rt10-r7s4/drivers/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:135 @ source "drivers/staging/Kconfig" source "drivers/platform/Kconfig" -source "drivers/soc/Kconfig" - source "drivers/clk/Kconfig" source "drivers/hwspinlock/Kconfig" Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7170.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7170.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7170.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:66 @ static inline struct adv7170 *to_adv7170 static char *inputs[] = { "pass_through", "play_back" }; -static enum v4l2_mbus_pixelcode adv7170_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_1X16, +static u32 adv7170_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, }; /* ----------------------------------------------------------------------- */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:266 @ static int adv7170_s_routing(struct v4l2 } static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(adv7170_codes)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:281 @ static int adv7170_g_fmt(struct v4l2_sub u8 val = adv7170_read(sd, 0x7); if ((val & 0x40) == (1 << 6)) - mf->code = V4L2_MBUS_FMT_UYVY8_1X16; + mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; mf->width = 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:300 @ static int adv7170_s_fmt(struct v4l2_sub int ret; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: val &= ~0x40; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: val |= 0x40; break; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7175.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7175.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7175.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:63 @ static inline struct adv7175 *to_adv7175 static char *inputs[] = { "pass_through", "play_back", "color_bar" }; -static enum v4l2_mbus_pixelcode adv7175_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_1X16, +static u32 adv7175_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, }; /* ----------------------------------------------------------------------- */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:304 @ static int adv7175_s_routing(struct v4l2 } static int adv7175_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(adv7175_codes)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:319 @ static int adv7175_g_fmt(struct v4l2_sub u8 val = adv7175_read(sd, 0x7); if ((val & 0x40) == (1 << 6)) - mf->code = V4L2_MBUS_FMT_UYVY8_1X16; + mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; mf->width = 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:338 @ static int adv7175_s_fmt(struct v4l2_sub int ret; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: val &= ~0x40; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: val |= 0x40; break; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7180.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7180.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7180.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:425 @ static void adv7180_exit_controls(struct } static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:440 @ static int adv7180_mbus_fmt(struct v4l2_ { struct adv7180_state *state = to_state(sd); - fmt->code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; fmt->field = V4L2_FIELD_INTERLACED; fmt->width = 720; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7183.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7183.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7183.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:424 @ static int adv7183_g_input_status(struct } static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:438 @ static int adv7183_try_mbus_fmt(struct v { struct adv7183 *decoder = to_adv7183(sd); - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; if (decoder->std & V4L2_STD_525_60) { fmt->field = V4L2_FIELD_SEQ_TB; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7604.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7604.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7604.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:91 @ struct adv7604_reg_seq { }; struct adv7604_format_info { - enum v4l2_mbus_pixelcode code; + u32 code; u8 op_ch_sel; bool rgb_out; bool swap_cb_cr; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:752 @ static void adv7604_write_reg_seq(struct */ static const struct adv7604_format_info adv7604_formats[] = { - { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, + { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, }; static const struct adv7604_format_info adv7611_formats[] = { - { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, + { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, }; static const struct adv7604_format_info * -adv7604_format_info(struct adv7604_state *state, enum v4l2_mbus_pixelcode code) +adv7604_format_info(struct adv7604_state *state, u32 code) { unsigned int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1920 @ static int adv7604_set_format(struct v4l info = adv7604_format_info(state, format->format.code); if (info == NULL) - info = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); + info = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); adv7604_fill_format(state, &format->format); format->format.code = info->code; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2810 @ static int adv7604_probe(struct i2c_clie } state->timings = cea640x480; - state->format = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); + state->format = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7604_ops); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7842.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/adv7842.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/adv7842.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1880 @ static int adv7842_s_routing(struct v4l2 } static int adv7842_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; /* Good enough for now */ - *code = V4L2_MBUS_FMT_FIXED; + *code = MEDIA_BUS_FMT_FIXED; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1896 @ static int adv7842_g_mbus_fmt(struct v4l fmt->width = state->timings.bt.width; fmt->height = state->timings.bt.height; - fmt->code = V4L2_MBUS_FMT_FIXED; + fmt->code = MEDIA_BUS_FMT_FIXED; fmt->field = V4L2_FIELD_NONE; if (state->mode == ADV7842_MODE_SDP) { Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/ak881x.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/ak881x.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/ak881x.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:105 @ static int ak881x_try_g_mbus_fmt(struct v4l_bound_align_image(&mf->width, 0, 720, 2, &mf->height, 0, ak881x->lines, 1, 0); mf->field = V4L2_FIELD_INTERLACED; - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:115 @ static int ak881x_s_mbus_fmt(struct v4l2 struct v4l2_mbus_framefmt *mf) { if (mf->field != V4L2_FIELD_INTERLACED || - mf->code != V4L2_MBUS_FMT_YUYV8_2X8) + mf->code != MEDIA_BUS_FMT_YUYV8_2X8) return -EINVAL; return ak881x_try_g_mbus_fmt(sd, mf); } static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/cx25840/cx25840-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/cx25840/cx25840-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/cx25840/cx25840-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1376 @ static int cx25840_s_mbus_fmt(struct v4l int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/m5mols/m5mols_core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/m5mols/m5mols_core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/m5mols/m5mols_core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ static struct v4l2_mbus_framefmt m5mols_ [M5MOLS_RESTYPE_MONITOR] = { .width = 1920, .height = 1080, - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }, [M5MOLS_RESTYPE_CAPTURE] = { .width = 1920, .height = 1080, - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:482 @ static int m5mols_get_version(struct v4l * __find_restype - Lookup M-5MOLS resolution type according to pixel code * @code: pixel code */ -static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code) +static enum m5mols_restype __find_restype(u32 code) { enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/ml86v7667.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/ml86v7667.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/ml86v7667.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:195 @ static int ml86v7667_g_input_status(stru } static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:210 @ static int ml86v7667_mbus_fmt(struct v4l { struct ml86v7667_priv *priv = to_ml86v7667(sd); - fmt->code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; /* The top field is always transferred first by the chip */ fmt->field = V4L2_FIELD_INTERLACED_TB; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9m032.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/mt9m032.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9m032.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:326 @ static int mt9m032_enum_mbus_code(struct if (code->index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_Y8_1X8; + code->code = MEDIA_BUS_FMT_Y8_1X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:334 @ static int mt9m032_enum_frame_size(struc struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8) + if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8) return -EINVAL; fse->min_width = MT9M032_COLUMN_SIZE_DEF; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:762 @ static int mt9m032_probe(struct i2c_clie sensor->format.width = sensor->crop.width; sensor->format.height = sensor->crop.height; - sensor->format.code = V4L2_MBUS_FMT_Y8_1X8; + sensor->format.code = MEDIA_BUS_FMT_Y8_1X8; sensor->format.field = V4L2_FIELD_NONE; sensor->format.colorspace = V4L2_COLORSPACE_SRGB; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9p031.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/mt9p031.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9p031.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:953 @ static int mt9p031_open(struct v4l2_subd format = v4l2_subdev_get_try_format(fh, 0); if (mt9p031->model == MT9P031_MODEL_MONOCHROME) - format->code = V4L2_MBUS_FMT_Y12_1X12; + format->code = MEDIA_BUS_FMT_Y12_1X12; else - format->code = V4L2_MBUS_FMT_SGRBG12_1X12; + format->code = MEDIA_BUS_FMT_SGRBG12_1X12; format->width = MT9P031_WINDOW_WIDTH_DEF; format->height = MT9P031_WINDOW_HEIGHT_DEF; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1123 @ static int mt9p031_probe(struct i2c_clie mt9p031->crop.top = MT9P031_ROW_START_DEF; if (mt9p031->model == MT9P031_MODEL_MONOCHROME) - mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12; + mt9p031->format.code = MEDIA_BUS_FMT_Y12_1X12; else - mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + mt9p031->format.code = MEDIA_BUS_FMT_SGRBG12_1X12; mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF; mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9t001.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/mt9t001.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9t001.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:336 @ static int mt9t001_enum_mbus_code(struct if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_SGRBG10_1X10; + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:344 @ static int mt9t001_enum_frame_size(struc struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) + if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) return -EINVAL; fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:795 @ static int mt9t001_open(struct v4l2_subd crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; format = v4l2_subdev_get_try_format(fh, 0); - format->code = V4L2_MBUS_FMT_SGRBG10_1X10; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; format->width = MT9T001_WINDOW_WIDTH_DEF + 1; format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; format->field = V4L2_FIELD_NONE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:920 @ static int mt9t001_probe(struct i2c_clie mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1; mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1; - mt9t001->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + mt9t001->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1; mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1; mt9t001->format.field = V4L2_FIELD_NONE; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9v011.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/mt9v011.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9v011.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:328 @ static int mt9v011_reset(struct v4l2_sub } static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_SGRBG8_1X8; + *code = MEDIA_BUS_FMT_SGRBG8_1X8; return 0; } static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8) + if (fmt->code != MEDIA_BUS_FMT_SGRBG8_1X8) return -EINVAL; v4l_bound_align_image(&fmt->width, 48, 639, 1, Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9v032.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/mt9v032.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/mt9v032.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:457 @ static int mt9v032_enum_mbus_code(struct if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_SGRBG10_1X10; + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:465 @ static int mt9v032_enum_frame_size(struc struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= 3 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) + if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) return -EINVAL; fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:817 @ static int mt9v032_open(struct v4l2_subd format = v4l2_subdev_get_try_format(fh, 0); if (mt9v032->model->color) - format->code = V4L2_MBUS_FMT_SGRBG10_1X10; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; else - format->code = V4L2_MBUS_FMT_Y10_1X10; + format->code = MEDIA_BUS_FMT_Y10_1X10; format->width = MT9V032_WINDOW_WIDTH_DEF; format->height = MT9V032_WINDOW_HEIGHT_DEF; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:969 @ static int mt9v032_probe(struct i2c_clie mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF; if (mt9v032->model->color) - mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + mt9v032->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; else - mt9v032->format.code = V4L2_MBUS_FMT_Y10_1X10; + mt9v032->format.code = MEDIA_BUS_FMT_Y10_1X10; mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF; mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/noon010pc30.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/noon010pc30.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/noon010pc30.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:115 @ MODULE_PARM_DESC(debug, "Enable module d #define REG_TERM 0xFFFF struct noon010_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 ispctl1_reg; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:178 @ static const struct noon010_frmsize noon /* Supported pixel formats. */ static const struct noon010_format noon010_formats[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x03, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x02, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x01, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x40, }, Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/ov7670.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/ov7670.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/ov7670.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:635 @ static int ov7670_detect(struct v4l2_sub * The magic matrix numbers come from OmniVision. */ static struct ov7670_format_struct { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; enum v4l2_colorspace colorspace; struct regval_list *regs; int cmatrix[CMATRIX_LEN]; } ov7670_formats[] = { { - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .regs = ov7670_fmt_yuv422, .cmatrix = { 128, -128, 0, -34, -94, 128 }, }, { - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_rgb444, .cmatrix = { 179, -179, 0, -61, -176, 228 }, }, { - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_rgb565, .cmatrix = { 179, -179, 0, -61, -176, 228 }, }, { - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_raw, .cmatrix = { 0, 0, 0, 0, 0, 0 }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:775 @ static void ov7675_get_framerate(struct pll_factor = PLL_FACTOR; clkrc++; - if (info->fmt->mbus_code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (info->fmt->mbus_code == MEDIA_BUS_FMT_SBGGR8_1X8) clkrc = (clkrc >> 1); tpf->numerator = 1; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:813 @ static int ov7675_set_framerate(struct v } else { clkrc = (5 * pll_factor * info->clock_speed * tpf->numerator) / (4 * tpf->denominator); - if (info->fmt->mbus_code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (info->fmt->mbus_code == MEDIA_BUS_FMT_SBGGR8_1X8) clkrc = (clkrc << 1); clkrc--; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:903 @ static int ov7670_set_hw(struct v4l2_sub static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= N_OV7670_FMTS) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/ov9650.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/ov9650.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/ov9650.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:387 @ static const struct ov965x_framesize ov9 }; struct ov965x_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_TSLB value, only bits [3:2] may be set. */ u8 tslb_reg; }; static const struct ov965x_pixfmt ov965x_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 0x00}, - { V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG, 0x04}, - { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG, 0x0c}, - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 0x08}, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 0x00}, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG, 0x04}, + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG, 0x0c}, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 0x08}, }; /* Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5c73m3/s5c73m3.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/s5c73m3/s5c73m3.h +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5c73m3/s5c73m3.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:30 @ #define DRIVER_NAME "S5C73M3" -#define S5C73M3_ISP_FMT V4L2_MBUS_FMT_VYUY8_2X8 -#define S5C73M3_JPEG_FMT V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 +#define S5C73M3_ISP_FMT MEDIA_BUS_FMT_VYUY8_2X8 +#define S5C73M3_JPEG_FMT MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 /* Subdevs pad index definitions */ enum s5c73m3_pads { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:405 @ struct s5c73m3 { const struct s5c73m3_frame_size *sensor_pix_size[2]; const struct s5c73m3_frame_size *oif_pix_size[2]; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; const struct s5c73m3_interval *fiv; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k4ecgx.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/s5k4ecgx.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k4ecgx.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:154 @ static const struct s5k4ecgx_frmsize s5k #define S5K4ECGX_NUM_PREV ARRAY_SIZE(s5k4ecgx_prev_sizes) struct s5k4ecgx_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_TC_PCFG_Format register value */ u16 reg_p_format; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:162 @ struct s5k4ecgx_pixfmt { /* By default value, output from sensor will be YUV422 0-255 */ static const struct s5k4ecgx_pixfmt s5k4ecgx_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, }; static const char * const s5k4ecgx_supply_names[] = { Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k5baf.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/s5k5baf.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k5baf.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:251 @ enum s5k5baf_gpio_id { #define NUM_ISP_PADS 2 struct s5k5baf_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_P_FMT(x) register value */ u16 reg_p_fmt; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:334 @ struct s5k5baf { }; static const struct s5k5baf_pixfmt s5k5baf_formats[] = { - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 }, /* range 16-240 */ - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 }, - { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, }; static struct v4l2_rect s5k5baf_cis_rect = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1209 @ static int s5k5baf_enum_mbus_code(struct if (code->pad == PAD_CIS) { if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_FIXED; + code->code = MEDIA_BUS_FMT_FIXED; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1230 @ static int s5k5baf_enum_frame_size(struc return -EINVAL; if (fse->pad == PAD_CIS) { - fse->code = V4L2_MBUS_FMT_FIXED; + fse->code = MEDIA_BUS_FMT_FIXED; fse->min_width = S5K5BAF_CIS_WIDTH; fse->max_width = S5K5BAF_CIS_WIDTH; fse->min_height = S5K5BAF_CIS_HEIGHT; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1255 @ static void s5k5baf_try_cis_format(struc { mf->width = S5K5BAF_CIS_WIDTH; mf->height = S5K5BAF_CIS_HEIGHT; - mf->code = V4L2_MBUS_FMT_FIXED; + mf->code = MEDIA_BUS_FMT_FIXED; mf->colorspace = V4L2_COLORSPACE_JPEG; mf->field = V4L2_FIELD_NONE; } Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k6a3.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/s5k6a3.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k6a3.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:83 @ static inline struct s5k6a3 *sd_to_s5k6a static const struct v4l2_mbus_framefmt s5k6a3_formats[] = { { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .colorspace = V4L2_COLORSPACE_SRGB, .field = V4L2_FIELD_NONE, } Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k6aa.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/s5k6aa.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/s5k6aa.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:194 @ struct s5k6aa_regval { }; struct s5k6aa_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_P_FMT(x) register value */ u16 reg_p_fmt; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:288 @ static struct s5k6aa_regval s5k6aa_analo /* TODO: Add RGB888 and Bayer format */ static const struct s5k6aa_pixfmt s5k6aa_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, /* range 16-240 */ - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 }, - { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, }; static const struct s5k6aa_interval s5k6aa_intervals[] = { Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa6752hs.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/saa6752hs.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa6752hs.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:565 @ static int saa6752hs_g_mbus_fmt(struct v h->video_format = SAA6752HS_VF_D1; f->width = v4l2_format_table[h->video_format].fmt.pix.width; f->height = v4l2_format_table[h->video_format].fmt.pix.height; - f->code = V4L2_MBUS_FMT_FIXED; + f->code = MEDIA_BUS_FMT_FIXED; f->field = V4L2_FIELD_INTERLACED; f->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:575 @ static int saa6752hs_try_mbus_fmt(struct { int dist_352, dist_480, dist_720; - f->code = V4L2_MBUS_FMT_FIXED; + f->code = MEDIA_BUS_FMT_FIXED; dist_352 = abs(f->width - 352); dist_480 = abs(f->width - 480); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:602 @ static int saa6752hs_s_mbus_fmt(struct v { struct saa6752hs_state *h = to_state(sd); - if (f->code != V4L2_MBUS_FMT_FIXED) + if (f->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; /* Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa7115.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/saa7115.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa7115.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1175 @ static int saa711x_s_sliced_fmt(struct v static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa717x.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/saa717x.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/saa717x.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1001 @ static int saa717x_s_mbus_fmt(struct v4l v4l2_dbg(1, debug, sd, "decoder set size\n"); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; /* FIXME need better bounds checking here */ Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/smiapp/smiapp-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/smiapp/smiapp-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/smiapp/smiapp-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:336 @ static void __smiapp_update_exposure_lim * orders must be defined. */ static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = { - { V4L2_MBUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, }; const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" }; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/imx074.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/imx074.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/imx074.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:74 @ /* IMX074 has only one fixed colorspace per pixelcode */ struct imx074_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:85 @ struct imx074 { }; static const struct imx074_datafmt imx074_colour_fmts[] = { - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static struct imx074 *to_imx074(const struct i2c_client *client) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:94 @ static struct imx074 *to_imx074(const st } /* Find a data format by a pixel code in an array */ -static const struct imx074_datafmt *imx074_find_datafmt(enum v4l2_mbus_pixelcode code) +static const struct imx074_datafmt *imx074_find_datafmt(u32 code) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:239 @ static int imx074_cropcap(struct v4l2_su } static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts)) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:77 @ config SOC_CAMERA_OV9740 help This is a ov9740 camera driver +config SOC_CAMERA_OV7740 + tristate "ov7740 camera support" + depends on SOC_CAMERA && I2C + help + This is a ov7740 camera driver + config SOC_CAMERA_RJ54N1 tristate "rj54n1cb0c support" depends on SOC_CAMERA && I2C Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/Makefile +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:11 @ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov26 obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o +obj-$(CONFIG_SOC_CAMERA_OV7740) += ov7740.o obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9m001.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/mt9m001.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9m001.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:56 @ /* MT9M001 has only one fixed colorspace per pixelcode */ struct mt9m001_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct mt9m001_datafmt *mt9m001_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt, + u32 code, const struct mt9m001_datafmt *fmt, int n) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ static const struct mt9m001_datafmt mt9m * Order important: first natively supported, * second supported with a GPIO extender */ - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { /* Order important - see above */ - {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, }; struct mt9m001 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:566 @ static struct v4l2_subdev_core_ops mt9m0 }; static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9m111.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/mt9m111.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9m111.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:185 @ static struct mt9m111_context context_b /* MT9M111 has only one fixed colorspace per pixelcode */ struct mt9m111_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, }; struct mt9m111 { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:221 @ struct mt9m111 { /* Find a data format by a pixel code */ static const struct mt9m111_datafmt *mt9m111_find_datafmt(struct mt9m111 *mt9m111, - enum v4l2_mbus_pixelcode code) + u32 code) { int i; for (i = 0; i < ARRAY_SIZE(mt9m111_colour_fmts); i++) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:334 @ static int mt9m111_setup_rect_ctx(struct } static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rect, - int width, int height, enum v4l2_mbus_pixelcode code) + int width, int height, u32 code) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); int ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:348 @ static int mt9m111_setup_geometry(struct if (!ret) ret = reg_write(WINDOW_HEIGHT, rect->height); - if (code != V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (code != MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* IFP in use, down-scaling possible */ if (!ret) ret = mt9m111_setup_rect_ctx(mt9m111, &context_b, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:396 @ static int mt9m111_s_crop(struct v4l2_su if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* Bayer format - even size lengths */ rect.width = ALIGN(rect.width, 2); rect.height = ALIGN(rect.height, 2); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:465 @ static int mt9m111_g_fmt(struct v4l2_sub } static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, - enum v4l2_mbus_pixelcode code) + u32 code) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); u16 data_outfmt2, mask_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER | @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:477 @ static int mt9m111_set_pixfmt(struct mt9 int ret; switch (code) { - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: data_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB; break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: data_outfmt2 = MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; break; - case V4L2_MBUS_FMT_BGR565_2X8_BE: + case MEDIA_BUS_FMT_BGR565_2X8_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_BGR565_2X8_LE: + case MEDIA_BUS_FMT_BGR565_2X8_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: data_outfmt2 = 0; break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:545 @ static int mt9m111_try_fmt(struct v4l2_s fmt = mt9m111_find_datafmt(mt9m111, mf->code); - bayer = fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; + bayer = fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE; /* * With Bayer format enforce even side lengths, but let the user play @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:557 @ static int mt9m111_try_fmt(struct v4l2_s rect->height = ALIGN(rect->height, 2); } - if (fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* IFP bypass mode, no scaling */ mf->width = rect->width; mf->height = rect->height; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:843 @ static struct v4l2_subdev_core_ops mt9m1 }; static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(mt9m111_colour_fmts)) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9t031.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/mt9t031.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9t031.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:348 @ static int mt9t031_g_fmt(struct v4l2_sub mf->width = mt9t031->rect.width / mt9t031->xskip; mf->height = mt9t031->rect.height / mt9t031->yskip; - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; mf->field = V4L2_FIELD_NONE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:370 @ static int mt9t031_s_fmt(struct v4l2_sub xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT); - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; /* mt9t031_set_params() doesn't change width and height */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:388 @ static int mt9t031_try_fmt(struct v4l2_s &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:676 @ static struct v4l2_subdev_core_ops mt9t0 }; static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_SBGGR10_1X10; + *code = MEDIA_BUS_FMT_SBGGR10_1X10; return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9t112.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/mt9t112.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9t112.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:80 @ struct ************************************************************************/ struct mt9t112_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 fmt; u16 order; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:106 @ struct mt9t112_priv { static const struct mt9t112_format mt9t112_cfmts[] = { { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 0, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 1, }, { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 2, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 3, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .fmt = 8, .order = 2, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .fmt = 4, .order = 2, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:843 @ static int mt9t112_s_stream(struct v4l2_ static int mt9t112_set_params(struct mt9t112_priv *priv, const struct v4l2_rect *rect, - enum v4l2_mbus_pixelcode code) + u32 code) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:956 @ static int mt9t112_try_fmt(struct v4l2_s break; if (i == priv->num_formats) { - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; } else { mf->colorspace = mt9t112_cfmts[i].colorspace; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:970 @ static int mt9t112_try_fmt(struct v4l2_s } static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1104 @ static int mt9t112_probe(struct i2c_clie /* Cannot fail: using the default supported pixel code */ if (!ret) - mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); + mt9t112_set_params(priv, &rect, MEDIA_BUS_FMT_UYVY8_2X8); else v4l2_clk_put(priv->clk); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9v022.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/mt9v022.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/mt9v022.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:88 @ MODULE_PARM_DESC(sensor_type, "Sensor ty /* MT9V022 has only one fixed colorspace per pixelcode */ struct mt9v022_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct mt9v022_datafmt *mt9v022_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt, + u32 code, const struct mt9v022_datafmt *fmt, int n) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:110 @ static const struct mt9v022_datafmt mt9v * Order important: first natively supported, * second supported with a GPIO extender */ - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { /* Order important - see above */ - {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, }; /* only registers with different addresses on different mt9v02x sensors */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:413 @ static int mt9v022_s_fmt(struct v4l2_sub * .try_mbus_fmt(), datawidth is from our supported format list */ switch (mf->code) { - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y10_1X10: if (mt9v022->model != MT9V022IX7ATM) return -EINVAL; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: if (mt9v022->model != MT9V022IX7ATC) return -EINVAL; break; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:446 @ static int mt9v022_try_fmt(struct v4l2_s struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); const struct mt9v022_datafmt *fmt; - int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mf->code == V4L2_MBUS_FMT_SBGGR10_1X10; + int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + mf->code == MEDIA_BUS_FMT_SBGGR10_1X10; v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH, align, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:762 @ static struct v4l2_subdev_core_ops mt9v0 }; static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov2640.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov2640.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov2640.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:16 @ * published by the Free Software Foundation. */ +#include <linux/clk.h> #include <linux/init.h> #include <linux/module.h> #include <linux/i2c.h> #include <linux/slab.h> #include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/v4l2-mediabus.h> #include <linux/videodev2.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:31 @ #include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> #include <media/v4l2-ctrls.h> +#include <media/v4l2-image-sizes.h> #define VAL_SET(x, mask, rshift, lshift) \ ((((x) >> rshift) & mask) << lshift) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:267 @ #define PID_OV2640 0x2642 #define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF)) +#define OV2640_SIZE(n, w, h, r) \ + {.name = n, .width = w , .height = h, .regs = r } + /* * Struct */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:278 @ struct regval_list { u8 value; }; -/* Supported resolutions */ -enum ov2640_width { - W_QCIF = 176, - W_QVGA = 320, - W_CIF = 352, - W_VGA = 640, - W_SVGA = 800, - W_XGA = 1024, - W_SXGA = 1280, - W_UXGA = 1600, -}; - -enum ov2640_height { - H_QCIF = 144, - H_QVGA = 240, - H_CIF = 288, - H_VGA = 480, - H_SVGA = 600, - H_XGA = 768, - H_SXGA = 1024, - H_UXGA = 1200, -}; - struct ov2640_win_size { char *name; - enum ov2640_width width; - enum ov2640_height height; + u32 width; + u32 height; const struct regval_list *regs; }; +#include "ov2643.h" + +enum ov264x_model { + MODEL_OV2640, + MODEL_OV2643, +}; struct ov2640_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; - enum v4l2_mbus_pixelcode cfmt_code; + u32 cfmt_code; struct v4l2_clk *clk; + struct clk *master_clk; const struct ov2640_win_size *win; + enum ov264x_model model; + + struct soc_camera_subdev_desc ssdd_dt; + struct gpio_desc *resetb_gpio; + struct gpio_desc *pwdn_gpio; }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:494 @ static const struct regval_list ov2640_i static const struct regval_list ov2640_size_change_preamble_regs[] = { { BANK_SEL, BANK_SEL_DSP }, { RESET, RESET_DVP }, - { HSIZE8, HSIZE8_SET(W_UXGA) }, - { VSIZE8, VSIZE8_SET(H_UXGA) }, + { HSIZE8, HSIZE8_SET(UXGA_WIDTH) }, + { VSIZE8, VSIZE8_SET(UXGA_HEIGHT) }, { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN }, - { HSIZE, HSIZE_SET(W_UXGA) }, - { VSIZE, VSIZE_SET(H_UXGA) }, + { HSIZE, HSIZE_SET(UXGA_WIDTH) }, + { VSIZE, VSIZE_SET(UXGA_HEIGHT) }, { XOFFL, XOFFL_SET(0) }, { YOFFL, YOFFL_SET(0) }, - { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) | + { VHYX, VHYX_HSIZE_SET(UXGA_WIDTH) | VHYX_VSIZE_SET(UXGA_HEIGHT) | VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)}, - { TEST, TEST_HSIZE_SET(W_UXGA) }, + { TEST, TEST_HSIZE_SET(UXGA_WIDTH) }, ENDMARKER, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:518 @ static const struct regval_list ov2640_s { RESET, 0x00} static const struct regval_list ov2640_qcif_regs[] = { - PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4), + PER_SIZE_REG_SEQ(QCIF_WIDTH, QCIF_HEIGHT, 3, 3, 4), ENDMARKER, }; static const struct regval_list ov2640_qvga_regs[] = { - PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4), + PER_SIZE_REG_SEQ(QVGA_WIDTH, QVGA_HEIGHT, 2, 2, 4), ENDMARKER, }; static const struct regval_list ov2640_cif_regs[] = { - PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8), + PER_SIZE_REG_SEQ(CIF_WIDTH, CIF_HEIGHT, 2, 2, 8), ENDMARKER, }; static const struct regval_list ov2640_vga_regs[] = { - PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2), + PER_SIZE_REG_SEQ(VGA_WIDTH, VGA_HEIGHT, 0, 0, 2), ENDMARKER, }; static const struct regval_list ov2640_svga_regs[] = { - PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2), + PER_SIZE_REG_SEQ(SVGA_WIDTH, SVGA_HEIGHT, 1, 1, 2), ENDMARKER, }; static const struct regval_list ov2640_xga_regs[] = { - PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2), + PER_SIZE_REG_SEQ(XGA_WIDTH, XGA_HEIGHT, 0, 0, 2), { CTRLI, 0x00}, ENDMARKER, }; static const struct regval_list ov2640_sxga_regs[] = { - PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2), + PER_SIZE_REG_SEQ(SXGA_WIDTH, SXGA_HEIGHT, 0, 0, 2), { CTRLI, 0x00}, { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE }, ENDMARKER, }; static const struct regval_list ov2640_uxga_regs[] = { - PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0), + PER_SIZE_REG_SEQ(UXGA_WIDTH, UXGA_HEIGHT, 0, 0, 0), { CTRLI, 0x00}, { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE }, ENDMARKER, }; -#define OV2640_SIZE(n, w, h, r) \ - {.name = n, .width = w , .height = h, .regs = r } - static const struct ov2640_win_size ov2640_supported_win_sizes[] = { - OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs), - OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs), - OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs), - OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs), - OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs), - OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs), - OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs), - OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs), + OV2640_SIZE("QCIF", QCIF_WIDTH, QCIF_HEIGHT, ov2640_qcif_regs), + OV2640_SIZE("QVGA", QVGA_WIDTH, QVGA_HEIGHT, ov2640_qvga_regs), + OV2640_SIZE("CIF", CIF_WIDTH, CIF_HEIGHT, ov2640_cif_regs), + OV2640_SIZE("VGA", VGA_WIDTH, VGA_HEIGHT, ov2640_vga_regs), + OV2640_SIZE("SVGA", SVGA_WIDTH, SVGA_HEIGHT, ov2640_svga_regs), + OV2640_SIZE("XGA", XGA_WIDTH, XGA_HEIGHT, ov2640_xga_regs), + OV2640_SIZE("SXGA", SXGA_WIDTH, SXGA_HEIGHT, ov2640_sxga_regs), + OV2640_SIZE("UXGA", UXGA_WIDTH, UXGA_HEIGHT, ov2640_uxga_regs), }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:619 @ static const struct regval_list ov2640_r ENDMARKER, }; -static enum v4l2_mbus_pixelcode ov2640_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_RGB565_2X8_BE, - V4L2_MBUS_FMT_RGB565_2X8_LE, +static u32 ov2640_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_RGB565_2X8_BE, + MEDIA_BUS_FMT_RGB565_2X8_LE, }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:757 @ static int ov2640_s_power(struct v4l2_su struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct ov2640_priv *priv = to_ov2640(client); + int ret; + + if (on) { + ret = clk_prepare_enable(priv->master_clk); + if (ret) + return ret; + } else { + clk_disable_unprepare(priv->master_clk); + } + + ret = soc_camera_set_power(&client->dev, ssdd, priv->clk, on); - return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); + if (ret && on) + clk_disable_unprepare(priv->master_clk); + + return ret; } /* Select the nearest higher resolution for capture */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:794 @ static const struct ov2640_win_size *ov2 return &ov2640_supported_win_sizes[default_size]; } +static const struct ov2640_win_size *ov2643_select_win(u32 *width, u32 *height) +{ + int i, default_size = ARRAY_SIZE(ov2643_supported_win_sizes) - 1; + + for (i = 0; i < ARRAY_SIZE(ov2643_supported_win_sizes); i++) { + if (ov2643_supported_win_sizes[i].width >= *width && + ov2643_supported_win_sizes[i].height >= *height) { + *width = ov2643_supported_win_sizes[i].width; + *height = ov2643_supported_win_sizes[i].height; + return &ov2643_supported_win_sizes[i]; + } + } + + *width = ov2643_supported_win_sizes[default_size].width; + *height = ov2643_supported_win_sizes[default_size].height; + return &ov2643_supported_win_sizes[default_size]; +} + + static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, - enum v4l2_mbus_pixelcode code) + u32 code) { struct ov2640_priv *priv = to_ov2640(client); const struct regval_list *selected_cfmt_regs; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:826 @ static int ov2640_set_params(struct i2c_ /* select format */ priv->cfmt_code = 0; switch (code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: dev_dbg(&client->dev, "%s: Selected cfmt RGB565 BE", __func__); selected_cfmt_regs = ov2640_rgb565_be_regs; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: dev_dbg(&client->dev, "%s: Selected cfmt RGB565 LE", __func__); selected_cfmt_regs = ov2640_rgb565_le_regs; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__); selected_cfmt_regs = ov2640_yuyv_regs; break; default: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__); selected_cfmt_regs = ov2640_uyvy_regs; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:889 @ err: return ret; } +static int ov2643_set_params(struct i2c_client *client, u32 *width, u32 *height, + u32 code) +{ + struct ov2640_priv *priv = to_ov2640(client); + int ret; + + /* select win */ + priv->win = ov2643_select_win(width, height); + + if (code != MEDIA_BUS_FMT_UYVY8_2X8) { + dev_err(&client->dev, "Not supported format: %d\n", code); + return -1; + } + + /* set size win */ + ret = ov2640_write_array(client, priv->win->regs); + + priv->cfmt_code = code; + *width = priv->win->width; + *height = priv->win->height; + + return 0; +} + static int ov2640_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:920 @ static int ov2640_g_fmt(struct v4l2_subd struct ov2640_priv *priv = to_ov2640(client); if (!priv->win) { - u32 width = W_SVGA, height = H_SVGA; + u32 width = SVGA_WIDTH, height = SVGA_HEIGHT; priv->win = ov2640_select_win(&width, &height); - priv->cfmt_code = V4L2_MBUS_FMT_UYVY8_2X8; + priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; } mf->width = priv->win->width; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:930 @ static int ov2640_g_fmt(struct v4l2_subd mf->code = priv->cfmt_code; switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } mf->field = V4L2_FIELD_NONE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:948 @ static int ov2640_s_fmt(struct v4l2_subd struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov2640_priv *priv = to_ov2640(client); int ret; switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } - ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); + if (priv->model == MODEL_OV2640) + ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); + else + ret = ov2643_set_params(client, &mf->width, &mf->height, mf->code); return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:975 @ static int ov2640_s_fmt(struct v4l2_subd static int ov2640_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov2640_priv *priv = to_ov2640(client); + /* * select suitable win, but don't store it */ - ov2640_select_win(&mf->width, &mf->height); + if (priv->model == MODEL_OV2640) + ov2640_select_win(&mf->width, &mf->height); + else + ov2643_select_win(&mf->width, &mf->height); mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1004 @ static int ov2640_try_fmt(struct v4l2_su } static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov2640_priv *priv = to_ov2640(client); + + if (priv->model == MODEL_OV2643) { + /* OV2643 only support UYVY format */ + if (index > 0) + return -EINVAL; + + *code = MEDIA_BUS_FMT_UYVY8_2X8; + return 0; + } + + /* OV2640 */ if (index >= ARRAY_SIZE(ov2640_codes)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1030 @ static int ov2640_g_crop(struct v4l2_sub { a->c.left = 0; a->c.top = 0; - a->c.width = W_UXGA; - a->c.height = H_UXGA; + a->c.width = UXGA_WIDTH; + a->c.height = UXGA_HEIGHT; a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1041 @ static int ov2640_cropcap(struct v4l2_su { a->bounds.left = 0; a->bounds.top = 0; - a->bounds.width = W_UXGA; - a->bounds.height = H_UXGA; + a->bounds.width = UXGA_WIDTH; + a->bounds.height = UXGA_HEIGHT; a->defrect = a->bounds; a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a->pixelaspect.numerator = 1; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1074 @ static int ov2640_video_probe(struct i2c switch (VERSION(pid, ver)) { case PID_OV2640: devname = "ov2640"; + priv->model = MODEL_OV2640; + break; + case PID_OV2643: + devname = "ov2643"; + priv->model = MODEL_OV2643; break; default: dev_err(&client->dev, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1141 @ static struct v4l2_subdev_ops ov2640_sub .video = &ov2640_subdev_video_ops, }; +/* OF probe functions */ +static int ov2640_hw_power(struct device *dev, int on) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov2640_priv *priv = to_ov2640(client); + + dev_dbg(&client->dev, "%s: %s the camera\n", + __func__, on ? "ENABLE" : "DISABLE"); + + if (priv->pwdn_gpio) + gpiod_direction_output(priv->pwdn_gpio, !on); + + return 0; +} + +static int ov2640_hw_reset(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov2640_priv *priv = to_ov2640(client); + + if (priv->resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv->resetb_gpio, 1); + usleep_range(3000, 5000); + gpiod_direction_output(priv->resetb_gpio, 0); + } + + return 0; +} + +static int ov2640_probe_dt(struct i2c_client *client, + struct ov2640_priv *priv) +{ + /* Request the reset GPIO deasserted */ + priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", + GPIOD_OUT_LOW); + if (!priv->resetb_gpio) + dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); + else if (IS_ERR(priv->resetb_gpio)) + return PTR_ERR(priv->resetb_gpio); + + /* Request the power down GPIO asserted */ + priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + if (!priv->pwdn_gpio) + dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); + else if (IS_ERR(priv->pwdn_gpio)) + return PTR_ERR(priv->pwdn_gpio); + + /* Initialize the soc_camera_subdev_desc */ + priv->ssdd_dt.power = ov2640_hw_power; + priv->ssdd_dt.reset = ov2640_hw_reset; + client->dev.platform_data = &priv->ssdd_dt; + + return 0; +} + /* * i2c_driver functions */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1209 @ static int ov2640_probe(struct i2c_clien struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret; - if (!ssdd) { - dev_err(&adapter->dev, - "OV2640: Missing platform_data for driver\n"); - return -EINVAL; - } - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&adapter->dev, "OV2640: I2C-Adapter doesn't support SMBUS\n"); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1222 @ static int ov2640_probe(struct i2c_clien return -ENOMEM; } + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return -EPROBE_DEFER; + + if (!ssdd && !client->dev.of_node) { + dev_err(&client->dev, "Missing platform_data for driver\n"); + ret = -EINVAL; + goto err_mclk; + } + + if (!ssdd) { + ret = ov2640_probe_dt(client, priv); + if (ret) + goto err_mclk; + } + + priv->master_clk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(priv->master_clk)) { + ret = PTR_ERR(priv->master_clk); + goto err_mclk; + } + v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); v4l2_ctrl_handler_init(&priv->hdl, 2); v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1251 @ static int ov2640_probe(struct i2c_clien v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) - return priv->hdl.error; - - priv->clk = v4l2_clk_get(&client->dev, "mclk"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto eclkget; + if (priv->hdl.error) { + ret = priv->hdl.error; + goto err_mclk; } ret = ov2640_video_probe(client); if (ret) { - v4l2_clk_put(priv->clk); -eclkget: - v4l2_ctrl_handler_free(&priv->hdl); + goto err_videoprobe; } else { dev_info(&adapter->dev, "OV2640 Probed\n"); } + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) + goto err_videoprobe; + + return 0; + +err_videoprobe: + v4l2_ctrl_handler_free(&priv->hdl); +err_mclk: + v4l2_clk_put(priv->clk); return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1280 @ static int ov2640_remove(struct i2c_clie { struct ov2640_priv *priv = to_ov2640(client); + v4l2_async_unregister_subdev(&priv->subdev); v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1293 @ static const struct i2c_device_id ov2640 }; MODULE_DEVICE_TABLE(i2c, ov2640_id); +static const struct of_device_id ov2640_of_match[] = { + {.compatible = "ovti,ov2640", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ov2640_of_match); + static struct i2c_driver ov2640_i2c_driver = { .driver = { .name = "ov2640", + .of_match_table = of_match_ptr(ov2640_of_match), }, .probe = ov2640_probe, .remove = ov2640_remove, Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov2643.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov2643.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#define PID_OV2643 0x2643 + +static const struct regval_list ov2643_yuv_uxga[]= { + {0x12, 0x80}, + {0xc3, 0x1f}, + {0xc4, 0xff}, + {0x3d, 0x48}, + {0xdd, 0xa5}, + {0x0e, 0xb4}, + {0x10, 0x0a}, + {0x11, 0x00}, + {0x0f, 0x14}, + {0x21, 0x25}, + {0x23, 0x0c}, + {0x12, 0x08}, + {0x39, 0x10}, + {0xcd, 0x12}, + {0x13, 0xff}, + {0x14, 0xa7}, + {0x15, 0x42}, + {0x3c, 0xa4}, + {0x18, 0x60}, + {0x19, 0x50}, + {0x1a, 0xe2}, + {0x37, 0xe8}, + {0x16, 0x90}, + {0x43, 0x00}, + {0x40, 0xfb}, + {0xa9, 0x44}, + {0x2f, 0xec}, + {0x35, 0x10}, + {0x36, 0x10}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0xd0, 0x93}, + {0xdc, 0x2b}, + {0xd9, 0x41}, + {0xd3, 0x02}, + {0x3d, 0x08}, + {0x0c, 0x00}, + {0x18, 0x2c}, + {0x19, 0x24}, + {0x1a, 0x71}, + {0x9b, 0x69}, + {0x9c, 0x7d}, + {0x9d, 0x7d}, + {0x9e, 0x69}, + {0x35, 0x04}, + {0x36, 0x04}, + {0x65, 0x12}, + {0x66, 0x20}, + {0x67, 0x39}, + {0x68, 0x4e}, + {0x69, 0x62}, + {0x6a, 0x74}, + {0x6b, 0x85}, + {0x6c, 0x92}, + {0x6d, 0x9e}, + {0x6e, 0xb2}, + {0x6f, 0xc0}, + {0x70, 0xcc}, + {0x71, 0xe0}, + {0x72, 0xee}, + {0x73, 0xf6}, + {0x74, 0x11}, + {0xab, 0x20}, + {0xac, 0x5b}, + {0xad, 0x05}, + {0xae, 0x1b}, + {0xaf, 0x76}, + {0xb0, 0x90}, + {0xb1, 0x90}, + {0xb2, 0x8c}, + {0xb3, 0x04}, + {0xb4, 0x98}, + {0x4c, 0x03}, + {0x4d, 0x30}, + {0x4e, 0x02}, + {0x4f, 0x5c}, + {0x50, 0x56}, + {0x51, 0x00}, + {0x52, 0x66}, + {0x53, 0x03}, + {0x54, 0x30}, + {0x55, 0x02}, + {0x56, 0x5c}, + {0x57, 0x40}, + {0x58, 0x00}, + {0x59, 0x66}, + {0x5a, 0x03}, + {0x5b, 0x20}, + {0x5c, 0x02}, + {0x5d, 0x5c}, + {0x5e, 0x3a}, + {0x5f, 0x00}, + {0x60, 0x66}, + {0x41, 0x1f}, + {0xb5, 0x01}, + {0xb6, 0x02}, + {0xb9, 0x40}, + {0xba, 0x28}, + {0xbf, 0x0c}, + {0xc0, 0x3e}, + {0xa3, 0x0a}, + {0xa4, 0x0f}, + {0xa5, 0x09}, + {0xa6, 0x16}, + {0x9f, 0x0a}, + {0xa0, 0x0f}, + {0xa7, 0x0a}, + {0xa8, 0x0f}, + {0xa1, 0x10}, + {0xa2, 0x04}, + {0xa9, 0x04}, + {0xaa, 0xa6}, + {0x75, 0x6a}, + {0x76, 0x11}, + {0x77, 0x92}, + {0x78, 0x21}, + {0x79, 0xe1}, + {0x7a, 0x02}, + {0x7c, 0x05}, + {0x7d, 0x08}, + {0x7e, 0x08}, + {0x7f, 0x7c}, + {0x80, 0x58}, + {0x81, 0x2a}, + {0x82, 0xc5}, + {0x83, 0x46}, + {0x84, 0x3a}, + {0x85, 0x54}, + {0x86, 0x44}, + {0x87, 0xf8}, + {0x88, 0x08}, + {0x89, 0x70}, + {0x8a, 0xf0}, + {0x8b, 0xf0}, + {0x90, 0xe3}, + {0x93, 0x10}, + {0x94, 0x20}, + {0x95, 0x10}, + {0x96, 0x18}, + {0x0f, 0x34}, + + {0x12, 0x80}, + {0xc3, 0x1f}, + {0xc4, 0xff}, + {0x3d, 0x48}, + {0xdd, 0xa5}, + {0x0e, 0xb4}, + {0x10, 0x0a}, + {0x11, 0x00}, + {0x0f, 0x14}, + {0x21, 0x25}, + {0x23, 0x0c}, + {0x12, 0x08}, + {0x39, 0x10}, + {0xcd, 0x12}, + {0x13, 0xff}, + {0x14, 0xa7}, + {0x15, 0x42}, + {0x3c, 0xa4}, + {0x18, 0x60}, + {0x19, 0x50}, + {0x1a, 0xe2}, + {0x37, 0xe8}, + {0x16, 0x90}, + {0x43, 0x00}, + {0x40, 0xfb}, + {0xa9, 0x44}, + {0x2f, 0xec}, + {0x35, 0x10}, + {0x36, 0x10}, + {0x0c, 0x00}, + {0x0d, 0x20}, /* YUV/RGB format */ + {0xd0, 0x93}, + {0xdc, 0x2b}, + {0xd9, 0x41}, + {0xd3, 0x02}, + {0x3d, 0x08}, + {0x0c, 0x00}, + {0x18, 0x2c}, + {0x19, 0x24}, + {0x1a, 0x71}, + {0x9b, 0x69}, + {0x9c, 0x7d}, + {0x9d, 0x7d}, + {0x9e, 0x69}, + {0x35, 0x04}, + {0x36, 0x04}, + {0x65, 0x12}, + {0x66, 0x20}, + {0x67, 0x39}, + {0x68, 0x4e}, + {0x69, 0x62}, + {0x6a, 0x74}, + {0x6b, 0x85}, + {0x6c, 0x92}, + {0x6d, 0x9e}, + {0x6e, 0xb2}, + {0x6f, 0xc0}, + {0x70, 0xcc}, + {0x71, 0xe0}, + {0x72, 0xee}, + {0x73, 0xf6}, + {0x74, 0x11}, + {0xab, 0x20}, + {0xac, 0x5b}, + {0xad, 0x05}, + {0xae, 0x1b}, + {0xaf, 0x76}, + {0xb0, 0x90}, + {0xb1, 0x90}, + {0xb2, 0x8c}, + {0xb3, 0x04}, + {0xb4, 0x98}, + {0x4c, 0x03}, + {0x4d, 0x30}, + {0x4e, 0x02}, + {0x4f, 0x5c}, + {0x50, 0x56}, + {0x51, 0x00}, + {0x52, 0x66}, + {0x53, 0x03}, + {0x54, 0x30}, + {0x55, 0x02}, + {0x56, 0x5c}, + {0x57, 0x40}, + {0x58, 0x00}, + {0x59, 0x66}, + {0x5a, 0x03}, + {0x5b, 0x20}, + {0x5c, 0x02}, + {0x5d, 0x5c}, + {0x5e, 0x3a}, + {0x5f, 0x00}, + {0x60, 0x66}, + {0x41, 0x1f}, + {0xb5, 0x01}, + {0xb6, 0x02}, + {0xb9, 0x40}, + {0xba, 0x28}, + {0xbf, 0x0c}, + {0xc0, 0x3e}, + {0xa3, 0x0a}, + {0xa4, 0x0f}, + {0xa5, 0x09}, + {0xa6, 0x16}, + {0x9f, 0x0a}, + {0xa0, 0x0f}, + {0xa7, 0x0a}, + {0xa8, 0x0f}, + {0xa1, 0x10}, + {0xa2, 0x04}, + {0xa9, 0x04}, + {0xaa, 0xa6}, + {0x75, 0x6a}, + {0x76, 0x11}, + {0x77, 0x92}, + {0x78, 0x21}, + {0x79, 0xe1}, + {0x7a, 0x02}, + {0x7c, 0x05}, + {0x7d, 0x08}, + {0x7e, 0x08}, + {0x7f, 0x7c}, + {0x80, 0x58}, + {0x81, 0x2a}, + {0x82, 0xc5}, + {0x83, 0x46}, + {0x84, 0x3a}, + {0x85, 0x54}, + {0x86, 0x44}, + {0x87, 0xf8}, + {0x88, 0x08}, + {0x89, 0x70}, + {0x8a, 0xf0}, + {0x8b, 0xf0}, + {0x90, 0xe3}, + {0x93, 0x10}, + {0x94, 0x20}, + {0x95, 0x10}, + {0x96, 0x18}, + {0x0f, 0x34}, + {0xFF, 0xFF}, +}; + +static const struct regval_list ov2643_yuv_swvga[]= { + {0x12, 0x80}, + {0xc3, 0x1f}, + {0xc4, 0xff}, + {0x3d, 0x48}, + {0xdd, 0xa5}, + {0x0e, 0xb4}, + {0x10, 0x0a}, + {0x11, 0x00}, + {0x0f, 0x14}, + {0x21, 0x25}, + {0x23, 0x0c}, + {0x12, 0x08}, + {0x39, 0x10}, + {0xcd, 0x12}, + {0x13, 0xff}, + {0x14, 0xa7}, + {0x15, 0x42}, + {0x3c, 0xa4}, + {0x18, 0x60}, + {0x19, 0x50}, + {0x1a, 0xe2}, + {0x37, 0xe8}, + {0x16, 0x90}, + {0x43, 0x00}, + {0x40, 0xfb}, + {0xa9, 0x44}, + {0x2f, 0xec}, + {0x35, 0x10}, + {0x36, 0x10}, + {0x0c, 0x00}, + {0x0d, 0x20}, /* YUV/RGB format */ + {0xd0, 0x93}, + {0xdc, 0x2b}, + {0xd9, 0x41}, + {0xd3, 0x02}, + {0x3d, 0x08}, + {0x0c, 0x00}, + {0x18, 0x2c}, + {0x19, 0x24}, + {0x1a, 0x71}, + {0x9b, 0x69}, + {0x9c, 0x7d}, + {0x9d, 0x7d}, + {0x9e, 0x69}, + {0x35, 0x04}, + {0x36, 0x04}, + {0x65, 0x12}, + {0x66, 0x20}, + {0x67, 0x39}, + {0x68, 0x4e}, + {0x69, 0x62}, + {0x6a, 0x74}, + {0x6b, 0x85}, + {0x6c, 0x92}, + {0x6d, 0x9e}, + {0x6e, 0xb2}, + {0x6f, 0xc0}, + {0x70, 0xcc}, + {0x71, 0xe0}, + {0x72, 0xee}, + {0x73, 0xf6}, + {0x74, 0x11}, + {0xab, 0x20}, + {0xac, 0x5b}, + {0xad, 0x05}, + {0xae, 0x1b}, + {0xaf, 0x76}, + {0xb0, 0x90}, + {0xb1, 0x90}, + {0xb2, 0x8c}, + {0xb3, 0x04}, + {0xb4, 0x98}, + {0x4c, 0x03}, + {0x4d, 0x30}, + {0x4e, 0x02}, + {0x4f, 0x5c}, + {0x50, 0x56}, + {0x51, 0x00}, + {0x52, 0x66}, + {0x53, 0x03}, + {0x54, 0x30}, + {0x55, 0x02}, + {0x56, 0x5c}, + {0x57, 0x40}, + {0x58, 0x00}, + {0x59, 0x66}, + {0x5a, 0x03}, + {0x5b, 0x20}, + {0x5c, 0x02}, + {0x5d, 0x5c}, + {0x5e, 0x3a}, + {0x5f, 0x00}, + {0x60, 0x66}, + {0x41, 0x1f}, + {0xb5, 0x01}, + {0xb6, 0x02}, + {0xb9, 0x40}, + {0xba, 0x28}, + {0xbf, 0x0c}, + {0xc0, 0x3e}, + {0xa3, 0x0a}, + {0xa4, 0x0f}, + {0xa5, 0x09}, + {0xa6, 0x16}, + {0x9f, 0x0a}, + {0xa0, 0x0f}, + {0xa7, 0x0a}, + {0xa8, 0x0f}, + {0xa1, 0x10}, + {0xa2, 0x04}, + {0xa9, 0x04}, + {0xaa, 0xa6}, + {0x75, 0x6a}, + {0x76, 0x11}, + {0x77, 0x92}, + {0x78, 0x21}, + {0x79, 0xe1}, + {0x7a, 0x02}, + {0x7c, 0x05}, + {0x7d, 0x08}, + {0x7e, 0x08}, + {0x7f, 0x7c}, + {0x80, 0x58}, + {0x81, 0x2a}, + {0x82, 0xc5}, + {0x83, 0x46}, + {0x84, 0x3a}, + {0x85, 0x54}, + {0x86, 0x44}, + {0x87, 0xf8}, + {0x88, 0x08}, + {0x89, 0x70}, + {0x8a, 0xf0}, + {0x8b, 0xf0}, + {0x90, 0xe3}, + {0x93, 0x10}, + {0x94, 0x20}, + {0x95, 0x10}, + {0x96, 0x18}, + {0x0f, 0x34}, + + {0x3d, 0x48}, + {0x0e, 0xb8}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x21, 0x98}, + {0x22, 0x00}, + {0x23, 0x06}, + {0x24, 0x32}, + {0x25, 0x04}, + {0x26, 0x25}, + {0x27, 0x84}, + {0x28, 0x40}, + {0x29, 0x04}, + {0x2a, 0xce}, + {0x2b, 0x02}, + {0x2c, 0x8a}, + {0x12, 0x09}, + {0x39, 0xd0}, + {0xcd, 0x13}, + {0xde, 0x7c}, + {0x3d, 0x08}, + {0x15, 0x42}, + {0xde, 0x7c}, + {0x0f, 0x24}, + {0xFF, 0xFF}, +}; + +static const struct regval_list ov2643_yuv_vga[]= { + {0x12, 0x80}, + {0xc3, 0x1f}, + {0xc4, 0xff}, + {0x3d, 0x48}, + {0xdd, 0xa5}, + {0x0e, 0xb4}, + {0x10, 0x0a}, + {0x11, 0x00}, + {0x0f, 0x14}, + {0x21, 0x25}, + {0x23, 0x0c}, + {0x12, 0x08}, + {0x39, 0x10}, + {0xcd, 0x12}, + {0x13, 0xff}, + {0x14, 0xa7}, + {0x15, 0x42}, + {0x3c, 0xa4}, + {0x18, 0x60}, + {0x19, 0x50}, + {0x1a, 0xe2}, + {0x37, 0xe8}, + {0x16, 0x90}, + {0x43, 0x00}, + {0x40, 0xfb}, + {0xa9, 0x44}, + {0x2f, 0xec}, + {0x35, 0x10}, + {0x36, 0x10}, + {0x0c, 0x00}, + {0x0d, 0x20}, /* YUV/RGB format */ + {0xd0, 0x93}, + {0xdc, 0x2b}, + {0xd9, 0x41}, + {0xd3, 0x02}, + {0x3d, 0x08}, + {0x0c, 0x00}, + {0x18, 0x2c}, + {0x19, 0x24}, + {0x1a, 0x71}, + {0x9b, 0x69}, + {0x9c, 0x7d}, + {0x9d, 0x7d}, + {0x9e, 0x69}, + {0x35, 0x04}, + {0x36, 0x04}, + {0x65, 0x12}, + {0x66, 0x20}, + {0x67, 0x39}, + {0x68, 0x4e}, + {0x69, 0x62}, + {0x6a, 0x74}, + {0x6b, 0x85}, + {0x6c, 0x92}, + {0x6d, 0x9e}, + {0x6e, 0xb2}, + {0x6f, 0xc0}, + {0x70, 0xcc}, + {0x71, 0xe0}, + {0x72, 0xee}, + {0x73, 0xf6}, + {0x74, 0x11}, + {0xab, 0x20}, + {0xac, 0x5b}, + {0xad, 0x05}, + {0xae, 0x1b}, + {0xaf, 0x76}, + {0xb0, 0x90}, + {0xb1, 0x90}, + {0xb2, 0x8c}, + {0xb3, 0x04}, + {0xb4, 0x98}, + {0x4c, 0x03}, + {0x4d, 0x30}, + {0x4e, 0x02}, + {0x4f, 0x5c}, + {0x50, 0x56}, + {0x51, 0x00}, + {0x52, 0x66}, + {0x53, 0x03}, + {0x54, 0x30}, + {0x55, 0x02}, + {0x56, 0x5c}, + {0x57, 0x40}, + {0x58, 0x00}, + {0x59, 0x66}, + {0x5a, 0x03}, + {0x5b, 0x20}, + {0x5c, 0x02}, + {0x5d, 0x5c}, + {0x5e, 0x3a}, + {0x5f, 0x00}, + {0x60, 0x66}, + {0x41, 0x1f}, + {0xb5, 0x01}, + {0xb6, 0x02}, + {0xb9, 0x40}, + {0xba, 0x28}, + {0xbf, 0x0c}, + {0xc0, 0x3e}, + {0xa3, 0x0a}, + {0xa4, 0x0f}, + {0xa5, 0x09}, + {0xa6, 0x16}, + {0x9f, 0x0a}, + {0xa0, 0x0f}, + {0xa7, 0x0a}, + {0xa8, 0x0f}, + {0xa1, 0x10}, + {0xa2, 0x04}, + {0xa9, 0x04}, + {0xaa, 0xa6}, + {0x75, 0x6a}, + {0x76, 0x11}, + {0x77, 0x92}, + {0x78, 0x21}, + {0x79, 0xe1}, + {0x7a, 0x02}, + {0x7c, 0x05}, + {0x7d, 0x08}, + {0x7e, 0x08}, + {0x7f, 0x7c}, + {0x80, 0x58}, + {0x81, 0x2a}, + {0x82, 0xc5}, + {0x83, 0x46}, + {0x84, 0x3a}, + {0x85, 0x54}, + {0x86, 0x44}, + {0x87, 0xf8}, + {0x88, 0x08}, + {0x89, 0x70}, + {0x8a, 0xf0}, + {0x8b, 0xf0}, + {0x90, 0xe3}, + {0x93, 0x10}, + {0x94, 0x20}, + {0x95, 0x10}, + {0x96, 0x18}, + {0x0f, 0x34}, + + {0x13, 0x00}, + {0x3d, 0x48}, + {0x0e, 0xb8}, + {0x20, 0x02}, + {0x21, 0x18}, + {0x22, 0x00}, + {0x23, 0x42}, + {0x24, 0x28}, + {0x25, 0x04}, + {0x26, 0x1e}, + {0x27, 0x04}, + {0x28, 0x40}, + {0x29, 0x04}, + {0x2a, 0xce}, + {0x2b, 0x02}, + {0x2c, 0x8a}, + {0x12, 0x09}, + {0x39, 0xd0}, + {0xcd, 0x13}, + {0xde, 0x7c}, + {0x3d, 0x08}, + {0x13, 0xff}, + {0x15, 0x42}, + {0xFF, 0xFF}, +}; + +static const struct ov2640_win_size ov2643_supported_win_sizes[] = { + OV2640_SIZE("VGA", VGA_WIDTH, VGA_HEIGHT, ov2643_yuv_vga), + OV2640_SIZE("SWVGA", XGA_WIDTH, SVGA_HEIGHT, ov2643_yuv_swvga), + OV2640_SIZE("UXGA", UXGA_WIDTH, UXGA_HEIGHT, ov2643_yuv_uxga), +}; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov5642.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov5642.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov5642.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:18 @ */ #include <linux/bitops.h> +#include <linux/clk.h> #include <linux/delay.h> +#include <linux/gpio.h> #include <linux/i2c.h> #include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_gpio.h> #include <linux/slab.h> #include <linux/videodev2.h> -#include <linux/module.h> #include <linux/v4l2-mediabus.h> #include <media/soc_camera.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:92 @ */ #define BLANKING_MIN_HEIGHT 1000 +struct ov5640_size { + int width; + int height; +}; + +static const struct ov5640_size ov5640_support_sizes[] = { + /* smaller resolution first */ + { .width = 640, .height = 480 }, /* VGA */ + { .width = 1280, .height = 960 }, /* 1280x960 */ +}; + struct regval_list { u16 reg_num; u8 value; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:618 @ static struct regval_list ov5642_default { 0xffff, 0xff }, }; +static struct regval_list ov5640_default_regs_init[] = { + {0x3103, 0x11}, + {0x3008, 0x82}, + + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0xff}, + {0x3018, 0xff}, + {0x3034, 0x1a}, + {0x3035, 0x11}, + {0x3036, 0x27}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x08}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9b}, + {0x3808, 0x02}, + {0x3809, 0x80}, + {0x380a, 0x01}, + {0x380b, 0xe0}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x64}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x58}, + {0x302e, 0x00}, + {0x4300, 0x32}, /* UYVY */ + {0x501f, 0x00}, + {0x4713, 0x03}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x35}, + {0x460c, 0x22}, + {0x4837, 0x22}, + {0x3824, 0x02}, + {0x5000, 0xa7}, + {0x5001, 0xa3}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0xffff, 0xff}, +}; + +static struct regval_list ov5640_default_regs_finalise[] = { + {0x3503, 0x00}, + {0x3c07, 0x08}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + + {0x3803, 0x04}, + {0x3807, 0x9b}, + {0x3808, 0x02}, + {0x3809, 0x80}, + {0x380a, 0x01}, + {0x380b, 0xe0}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3813, 0x06}, + + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x62}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4004, 0x02}, + {0x4713, 0x03}, + {0x4407, 0x04}, + {0x460b, 0x35}, + {0x460c, 0x22}, + {0x3824, 0x02}, + {0x5001, 0xa3}, + {0xffff, 0xff}, +}; + +static struct regval_list ov5640_default_regs_finalise_960p[] = { + {0x3800, 0x0 }, + {0x3801, 0x0 }, + {0x3802, 0x0 }, + {0x3803, 0x0 }, + {0x380c, 0xB }, + {0x380d, 0x1C }, + {0x380e, 0x7 }, + {0x380f, 0xB0 }, + {0x3808, 0x5 }, + {0x3809, 0x0 }, + {0x380A, 0x3 }, + {0x380B, 0xC0 }, + {0x3804, 0xA }, + {0x3805, 0x3F }, + {0x3806, 0x7 }, + {0x3807, 0x9F }, + {0x3810, 0x0 }, + {0x3811, 0x20,}, + {0x3812, 0x0 }, + {0x3813, 0x10,}, + {0x3814, 0x11,}, + {0x3815, 0x11,}, + {0x5001, 0xa3 }, + {0xffff, 0xff}, +}; + +static struct regval_list ov5640_afc_regs_init[]= { + {0x3000 ,0x20}, + {0x8000 ,0x02}, + {0x8001 ,0x0f}, + {0x8002 ,0xe0}, + {0x8003 ,0x02}, + {0x8004 ,0x09}, + {0x8005 ,0x28}, + {0x8006 ,0xc2}, + {0x8007 ,0x01}, + {0x8008 ,0x22}, + {0x8009 ,0x22}, + {0x800a ,0x00}, + {0x800b ,0x02}, + {0x800c ,0x0d}, + {0x800d ,0xea}, + {0x800e ,0x30}, + {0x800f ,0x01}, + {0x8010 ,0x03}, + {0x8011 ,0x02}, + {0x8012 ,0x02}, + {0x8013 ,0xa6}, + {0x8014 ,0x30}, + {0x8015 ,0x02}, + {0x8016 ,0x03}, + {0x8017 ,0x02}, + {0x8018 ,0x02}, + {0x8019 ,0xa6}, + {0x801a ,0x90}, + {0x801b ,0x51}, + {0x801c ,0xa5}, + {0x801d ,0xe0}, + {0x801e ,0x78}, + {0x801f ,0x93}, + {0x8020 ,0xf6}, + {0x8021 ,0xa3}, + {0x8022 ,0xe0}, + {0x8023 ,0x08}, + {0x8024 ,0xf6}, + {0x8025 ,0xa3}, + {0x8026 ,0xe0}, + {0x8027 ,0x08}, + {0x8028 ,0xf6}, + {0x8029 ,0xe5}, + {0x802a ,0x1f}, + {0x802b ,0x70}, + {0x802c ,0x4f}, + {0x802d ,0x75}, + {0x802e ,0x1e}, + {0x802f ,0x20}, + {0x8030 ,0xd2}, + {0x8031 ,0x35}, + {0x8032 ,0xd3}, + {0x8033 ,0x78}, + {0x8034 ,0x4f}, + {0x8035 ,0xe6}, + {0x8036 ,0x94}, + {0x8037 ,0x00}, + {0x8038 ,0x18}, + {0x8039 ,0xe6}, + {0x803a ,0x94}, + {0x803b ,0x00}, + {0x803c ,0x40}, + {0x803d ,0x07}, + {0x803e ,0xe6}, + {0x803f ,0xfe}, + {0x8040 ,0x08}, + {0x8041 ,0xe6}, + {0x8042 ,0xff}, + {0x8043 ,0x80}, + {0x8044 ,0x03}, + {0x8045 ,0x12}, + {0x8046 ,0x0c}, + {0x8047 ,0x67}, + {0x8048 ,0x78}, + {0x8049 ,0x7e}, + {0x804a ,0xa6}, + {0x804b ,0x06}, + {0x804c ,0x08}, + {0x804d ,0xa6}, + {0x804e ,0x07}, + {0x804f ,0x78}, + {0x8050 ,0x8b}, + {0x8051 ,0xa6}, + {0x8052 ,0x09}, + {0x8053 ,0x18}, + {0x8054 ,0x76}, + {0x8055 ,0x01}, + {0x8056 ,0x12}, + {0x8057 ,0x0c}, + {0x8058 ,0x67}, + {0x8059 ,0x78}, + {0x805a ,0x4e}, + {0x805b ,0xa6}, + {0x805c ,0x06}, + {0x805d ,0x08}, + {0x805e ,0xa6}, + {0x805f ,0x07}, + {0x8060 ,0x78}, + {0x8061 ,0x8b}, + {0x8062 ,0xe6}, + {0x8063 ,0x78}, + {0x8064 ,0x6e}, + {0x8065 ,0xf6}, + {0x8066 ,0x75}, + {0x8067 ,0x1f}, + {0x8068 ,0x01}, + {0x8069 ,0x78}, + {0x806a ,0x93}, + {0x806b ,0xe6}, + {0x806c ,0x78}, + {0x806d ,0x90}, + {0x806e ,0xf6}, + {0x806f ,0x78}, + {0x8070 ,0x94}, + {0x8071 ,0xe6}, + {0x8072 ,0x78}, + {0x8073 ,0x91}, + {0x8074 ,0xf6}, + {0x8075 ,0x78}, + {0x8076 ,0x95}, + {0x8077 ,0xe6}, + {0x8078 ,0x78}, + {0x8079 ,0x92}, + {0x807a ,0xf6}, + {0x807b ,0x22}, + {0x807c ,0x79}, + {0x807d ,0x90}, + {0x807e ,0xe7}, + {0x807f ,0xd3}, + {0x8080 ,0x78}, + {0x8081 ,0x93}, + {0x8082 ,0x96}, + {0x8083 ,0x40}, + {0x8084 ,0x05}, + {0x8085 ,0xe7}, + {0x8086 ,0x96}, + {0x8087 ,0xff}, + {0x8088 ,0x80}, + {0x8089 ,0x08}, + {0x808a ,0xc3}, + {0x808b ,0x79}, + {0x808c ,0x93}, + {0x808d ,0xe7}, + {0x808e ,0x78}, + {0x808f ,0x90}, + {0x8090 ,0x96}, + {0x8091 ,0xff}, + {0x8092 ,0x78}, + {0x8093 ,0x88}, + {0x8094 ,0x76}, + {0x8095 ,0x00}, + {0x8096 ,0x08}, + {0x8097 ,0xa6}, + {0x8098 ,0x07}, + {0x8099 ,0x79}, + {0x809a ,0x91}, + {0x809b ,0xe7}, + {0x809c ,0xd3}, + {0x809d ,0x78}, + {0x809e ,0x94}, + {0x809f ,0x96}, + {0x80a0 ,0x40}, + {0x80a1 ,0x05}, + {0x80a2 ,0xe7}, + {0x80a3 ,0x96}, + {0x80a4 ,0xff}, + {0x80a5 ,0x80}, + {0x80a6 ,0x08}, + {0x80a7 ,0xc3}, + {0x80a8 ,0x79}, + {0x80a9 ,0x94}, + {0x80aa ,0xe7}, + {0x80ab ,0x78}, + {0x80ac ,0x91}, + {0x80ad ,0x96}, + {0x80ae ,0xff}, + {0x80af ,0x12}, + {0x80b0 ,0x0c}, + {0x80b1 ,0xb0}, + {0x80b2 ,0x79}, + {0x80b3 ,0x92}, + {0x80b4 ,0xe7}, + {0x80b5 ,0xd3}, + {0x80b6 ,0x78}, + {0x80b7 ,0x95}, + {0x80b8 ,0x96}, + {0x80b9 ,0x40}, + {0x80ba ,0x05}, + {0x80bb ,0xe7}, + {0x80bc ,0x96}, + {0x80bd ,0xff}, + {0x80be ,0x80}, + {0x80bf ,0x08}, + {0x80c0 ,0xc3}, + {0x80c1 ,0x79}, + {0x80c2 ,0x95}, + {0x80c3 ,0xe7}, + {0x80c4 ,0x78}, + {0x80c5 ,0x92}, + {0x80c6 ,0x96}, + {0x80c7 ,0xff}, + {0x80c8 ,0x12}, + {0x80c9 ,0x0c}, + {0x80ca ,0xb0}, + {0x80cb ,0x12}, + {0x80cc ,0x0c}, + {0x80cd ,0x67}, + {0x80ce ,0x78}, + {0x80cf ,0x8a}, + {0x80d0 ,0xe6}, + {0x80d1 ,0x25}, + {0x80d2 ,0xe0}, + {0x80d3 ,0x24}, + {0x80d4 ,0x4e}, + {0x80d5 ,0xf8}, + {0x80d6 ,0xa6}, + {0x80d7 ,0x06}, + {0x80d8 ,0x08}, + {0x80d9 ,0xa6}, + {0x80da ,0x07}, + {0x80db ,0x78}, + {0x80dc ,0x8a}, + {0x80dd ,0xe6}, + {0x80de ,0x24}, + {0x80df ,0x6e}, + {0x80e0 ,0xf8}, + {0x80e1 ,0xa6}, + {0x80e2 ,0x09}, + {0x80e3 ,0x90}, + {0x80e4 ,0x0e}, + {0x80e5 ,0x93}, + {0x80e6 ,0xe4}, + {0x80e7 ,0x93}, + {0x80e8 ,0x24}, + {0x80e9 ,0xff}, + {0x80ea ,0xff}, + {0x80eb ,0xe4}, + {0x80ec ,0x34}, + {0x80ed ,0xff}, + {0x80ee ,0xfe}, + {0x80ef ,0x78}, + {0x80f0 ,0x8a}, + {0x80f1 ,0xe6}, + {0x80f2 ,0x24}, + {0x80f3 ,0x01}, + {0x80f4 ,0xfd}, + {0x80f5 ,0xe4}, + {0x80f6 ,0x33}, + {0x80f7 ,0xfc}, + {0x80f8 ,0xd3}, + {0x80f9 ,0xed}, + {0x80fa ,0x9f}, + {0x80fb ,0xee}, + {0x80fc ,0x64}, + {0x80fd ,0x80}, + {0x80fe ,0xf8}, + {0x80ff ,0xec}, + {0x8100 ,0x64}, + {0x8101 ,0x80}, + {0x8102 ,0x98}, + {0x8103 ,0x40}, + {0x8104 ,0x04}, + {0x8105 ,0x7f}, + {0x8106 ,0x00}, + {0x8107 ,0x80}, + {0x8108 ,0x05}, + {0x8109 ,0x78}, + {0x810a ,0x8a}, + {0x810b ,0xe6}, + {0x810c ,0x04}, + {0x810d ,0xff}, + {0x810e ,0x78}, + {0x810f ,0x8a}, + {0x8110 ,0xa6}, + {0x8111 ,0x07}, + {0x8112 ,0xe5}, + {0x8113 ,0x1f}, + {0x8114 ,0xb4}, + {0x8115 ,0x01}, + {0x8116 ,0x0a}, + {0x8117 ,0xe6}, + {0x8118 ,0x60}, + {0x8119 ,0x03}, + {0x811a ,0x02}, + {0x811b ,0x02}, + {0x811c ,0xa6}, + {0x811d ,0x75}, + {0x811e ,0x1f}, + {0x811f ,0x02}, + {0x8120 ,0x22}, + {0x8121 ,0x78}, + {0x8122 ,0x4e}, + {0x8123 ,0xe6}, + {0x8124 ,0xfe}, + {0x8125 ,0x08}, + {0x8126 ,0xe6}, + {0x8127 ,0xff}, + {0x8128 ,0x78}, + {0x8129 ,0x80}, + {0x812a ,0xa6}, + {0x812b ,0x06}, + {0x812c ,0x08}, + {0x812d ,0xa6}, + {0x812e ,0x07}, + {0x812f ,0x78}, + {0x8130 ,0x4e}, + {0x8131 ,0xe6}, + {0x8132 ,0xfe}, + {0x8133 ,0x08}, + {0x8134 ,0xe6}, + {0x8135 ,0xff}, + {0x8136 ,0x78}, + {0x8137 ,0x82}, + {0x8138 ,0xa6}, + {0x8139 ,0x06}, + {0x813a ,0x08}, + {0x813b ,0xa6}, + {0x813c ,0x07}, + {0x813d ,0x78}, + {0x813e ,0x6e}, + {0x813f ,0xe6}, + {0x8140 ,0x78}, + {0x8141 ,0x8c}, + {0x8142 ,0xf6}, + {0x8143 ,0x78}, + {0x8144 ,0x6e}, + {0x8145 ,0xe6}, + {0x8146 ,0x78}, + {0x8147 ,0x8d}, + {0x8148 ,0xf6}, + {0x8149 ,0x7f}, + {0x814a ,0x01}, + {0x814b ,0x90}, + {0x814c ,0x0e}, + {0x814d ,0x93}, + {0x814e ,0xe4}, + {0x814f ,0x93}, + {0x8150 ,0xfe}, + {0x8151 ,0xef}, + {0x8152 ,0xc3}, + {0x8153 ,0x9e}, + {0x8154 ,0x50}, + {0x8155 ,0x5f}, + {0x8156 ,0xef}, + {0x8157 ,0x25}, + {0x8158 ,0xe0}, + {0x8159 ,0x24}, + {0x815a ,0x4f}, + {0x815b ,0xf9}, + {0x815c ,0xc3}, + {0x815d ,0x78}, + {0x815e ,0x81}, + {0x815f ,0xe6}, + {0x8160 ,0x97}, + {0x8161 ,0x18}, + {0x8162 ,0xe6}, + {0x8163 ,0x19}, + {0x8164 ,0x97}, + {0x8165 ,0x50}, + {0x8166 ,0x0a}, + {0x8167 ,0x12}, + {0x8168 ,0x0c}, + {0x8169 ,0x98}, + {0x816a ,0x78}, + {0x816b ,0x80}, + {0x816c ,0xa6}, + {0x816d ,0x04}, + {0x816e ,0x08}, + {0x816f ,0xa6}, + {0x8170 ,0x05}, + {0x8171 ,0x74}, + {0x8172 ,0x6e}, + {0x8173 ,0x2f}, + {0x8174 ,0xf9}, + {0x8175 ,0x78}, + {0x8176 ,0x8c}, + {0x8177 ,0xe6}, + {0x8178 ,0xc3}, + {0x8179 ,0x97}, + {0x817a ,0x50}, + {0x817b ,0x08}, + {0x817c ,0x74}, + {0x817d ,0x6e}, + {0x817e ,0x2f}, + {0x817f ,0xf8}, + {0x8180 ,0xe6}, + {0x8181 ,0x78}, + {0x8182 ,0x8c}, + {0x8183 ,0xf6}, + {0x8184 ,0xef}, + {0x8185 ,0x25}, + {0x8186 ,0xe0}, + {0x8187 ,0x24}, + {0x8188 ,0x4f}, + {0x8189 ,0xf9}, + {0x818a ,0xd3}, + {0x818b ,0x78}, + {0x818c ,0x83}, + {0x818d ,0xe6}, + {0x818e ,0x97}, + {0x818f ,0x18}, + {0x8190 ,0xe6}, + {0x8191 ,0x19}, + {0x8192 ,0x97}, + {0x8193 ,0x40}, + {0x8194 ,0x0a}, + {0x8195 ,0x12}, + {0x8196 ,0x0c}, + {0x8197 ,0x98}, + {0x8198 ,0x78}, + {0x8199 ,0x82}, + {0x819a ,0xa6}, + {0x819b ,0x04}, + {0x819c ,0x08}, + {0x819d ,0xa6}, + {0x819e ,0x05}, + {0x819f ,0x74}, + {0x81a0 ,0x6e}, + {0x81a1 ,0x2f}, + {0x81a2 ,0xf9}, + {0x81a3 ,0x78}, + {0x81a4 ,0x8d}, + {0x81a5 ,0xe6}, + {0x81a6 ,0xd3}, + {0x81a7 ,0x97}, + {0x81a8 ,0x40}, + {0x81a9 ,0x08}, + {0x81aa ,0x74}, + {0x81ab ,0x6e}, + {0x81ac ,0x2f}, + {0x81ad ,0xf8}, + {0x81ae ,0xe6}, + {0x81af ,0x78}, + {0x81b0 ,0x8d}, + {0x81b1 ,0xf6}, + {0x81b2 ,0x0f}, + {0x81b3 ,0x80}, + {0x81b4 ,0x96}, + {0x81b5 ,0xc3}, + {0x81b6 ,0x79}, + {0x81b7 ,0x81}, + {0x81b8 ,0xe7}, + {0x81b9 ,0x78}, + {0x81ba ,0x83}, + {0x81bb ,0x96}, + {0x81bc ,0xff}, + {0x81bd ,0x19}, + {0x81be ,0xe7}, + {0x81bf ,0x18}, + {0x81c0 ,0x96}, + {0x81c1 ,0x78}, + {0x81c2 ,0x84}, + {0x81c3 ,0xf6}, + {0x81c4 ,0x08}, + {0x81c5 ,0xa6}, + {0x81c6 ,0x07}, + {0x81c7 ,0xc3}, + {0x81c8 ,0x79}, + {0x81c9 ,0x8c}, + {0x81ca ,0xe7}, + {0x81cb ,0x78}, + {0x81cc ,0x8d}, + {0x81cd ,0x96}, + {0x81ce ,0x08}, + {0x81cf ,0xf6}, + {0x81d0 ,0x12}, + {0x81d1 ,0x0c}, + {0x81d2 ,0xa4}, + {0x81d3 ,0x40}, + {0x81d4 ,0x05}, + {0x81d5 ,0x09}, + {0x81d6 ,0xe7}, + {0x81d7 ,0x08}, + {0x81d8 ,0x80}, + {0x81d9 ,0x06}, + {0x81da ,0xc3}, + {0x81db ,0x79}, + {0x81dc ,0x7f}, + {0x81dd ,0xe7}, + {0x81de ,0x78}, + {0x81df ,0x81}, + {0x81e0 ,0x96}, + {0x81e1 ,0xff}, + {0x81e2 ,0x19}, + {0x81e3 ,0xe7}, + {0x81e4 ,0x18}, + {0x81e5 ,0x96}, + {0x81e6 ,0xfe}, + {0x81e7 ,0x78}, + {0x81e8 ,0x86}, + {0x81e9 ,0xa6}, + {0x81ea ,0x06}, + {0x81eb ,0x08}, + {0x81ec ,0xa6}, + {0x81ed ,0x07}, + {0x81ee ,0x79}, + {0x81ef ,0x8c}, + {0x81f0 ,0xe7}, + {0x81f1 ,0xd3}, + {0x81f2 ,0x78}, + {0x81f3 ,0x8b}, + {0x81f4 ,0x96}, + {0x81f5 ,0x40}, + {0x81f6 ,0x05}, + {0x81f7 ,0xe7}, + {0x81f8 ,0x96}, + {0x81f9 ,0xff}, + {0x81fa ,0x80}, + {0x81fb ,0x08}, + {0x81fc ,0xc3}, + {0x81fd ,0x79}, + {0x81fe ,0x8b}, + {0x81ff ,0xe7}, + {0x8200 ,0x78}, + {0x8201 ,0x8c}, + {0x8202 ,0x96}, + {0x8203 ,0xff}, + {0x8204 ,0x78}, + {0x8205 ,0x8f}, + {0x8206 ,0xa6}, + {0x8207 ,0x07}, + {0x8208 ,0xe5}, + {0x8209 ,0x1f}, + {0x820a ,0x64}, + {0x820b ,0x02}, + {0x820c ,0x60}, + {0x820d ,0x03}, + {0x820e ,0x02}, + {0x820f ,0x02}, + {0x8210 ,0x92}, + {0x8211 ,0x90}, + {0x8212 ,0x0e}, + {0x8213 ,0x91}, + {0x8214 ,0x93}, + {0x8215 ,0xff}, + {0x8216 ,0x18}, + {0x8217 ,0xe6}, + {0x8218 ,0xc3}, + {0x8219 ,0x9f}, + {0x821a ,0x40}, + {0x821b ,0x03}, + {0x821c ,0x02}, + {0x821d ,0x02}, + {0x821e ,0xa6}, + {0x821f ,0x78}, + {0x8220 ,0x84}, + {0x8221 ,0x12}, + {0x8222 ,0x0c}, + {0x8223 ,0x89}, + {0x8224 ,0x12}, + {0x8225 ,0x0c}, + {0x8226 ,0x5e}, + {0x8227 ,0x90}, + {0x8228 ,0x0e}, + {0x8229 ,0x8e}, + {0x822a ,0x12}, + {0x822b ,0x0c}, + {0x822c ,0x77}, + {0x822d ,0x78}, + {0x822e ,0x80}, + {0x822f ,0xe6}, + {0x8230 ,0xfe}, + {0x8231 ,0x08}, + {0x8232 ,0xe6}, + {0x8233 ,0xff}, + {0x8234 ,0x12}, + {0x8235 ,0x0c}, + {0x8236 ,0xba}, + {0x8237 ,0x7b}, + {0x8238 ,0x04}, + {0x8239 ,0x12}, + {0x823a ,0x0c}, + {0x823b ,0x4c}, + {0x823c ,0xc3}, + {0x823d ,0x12}, + {0x823e ,0x06}, + {0x823f ,0xa6}, + {0x8240 ,0x50}, + {0x8241 ,0x64}, + {0x8242 ,0x90}, + {0x8243 ,0x0e}, + {0x8244 ,0x92}, + {0x8245 ,0xe4}, + {0x8246 ,0x93}, + {0x8247 ,0xff}, + {0x8248 ,0x78}, + {0x8249 ,0x8f}, + {0x824a ,0xe6}, + {0x824b ,0x9f}, + {0x824c ,0x40}, + {0x824d ,0x02}, + {0x824e ,0x80}, + {0x824f ,0x11}, + {0x8250 ,0x90}, + {0x8251 ,0x0e}, + {0x8252 ,0x90}, + {0x8253 ,0xe4}, + {0x8254 ,0x93}, + {0x8255 ,0xff}, + {0x8256 ,0xd3}, + {0x8257 ,0x78}, + {0x8258 ,0x89}, + {0x8259 ,0xe6}, + {0x825a ,0x9f}, + {0x825b ,0x18}, + {0x825c ,0xe6}, + {0x825d ,0x94}, + {0x825e ,0x00}, + {0x825f ,0x40}, + {0x8260 ,0x03}, + {0x8261 ,0x75}, + {0x8262 ,0x1f}, + {0x8263 ,0x05}, + {0x8264 ,0x78}, + {0x8265 ,0x86}, + {0x8266 ,0x12}, + {0x8267 ,0x0c}, + {0x8268 ,0x89}, + {0x8269 ,0x12}, + {0x826a ,0x0c}, + {0x826b ,0x5e}, + {0x826c ,0x90}, + {0x826d ,0x0e}, + {0x826e ,0x8f}, + {0x826f ,0x12}, + {0x8270 ,0x0c}, + {0x8271 ,0x77}, + {0x8272 ,0x12}, + {0x8273 ,0x0c}, + {0x8274 ,0xa4}, + {0x8275 ,0x40}, + {0x8276 ,0x02}, + {0x8277 ,0x80}, + {0x8278 ,0x02}, + {0x8279 ,0x78}, + {0x827a ,0x80}, + {0x827b ,0xe6}, + {0x827c ,0xfe}, + {0x827d ,0x08}, + {0x827e ,0xe6}, + {0x827f ,0xff}, + {0x8280 ,0x12}, + {0x8281 ,0x0c}, + {0x8282 ,0xba}, + {0x8283 ,0x7b}, + {0x8284 ,0x10}, + {0x8285 ,0x12}, + {0x8286 ,0x0c}, + {0x8287 ,0x4c}, + {0x8288 ,0xd3}, + {0x8289 ,0x12}, + {0x828a ,0x06}, + {0x828b ,0xa6}, + {0x828c ,0x40}, + {0x828d ,0x18}, + {0x828e ,0x75}, + {0x828f ,0x1f}, + {0x8290 ,0x05}, + {0x8291 ,0x22}, + {0x8292 ,0xe5}, + {0x8293 ,0x1f}, + {0x8294 ,0xb4}, + {0x8295 ,0x05}, + {0x8296 ,0x0f}, + {0x8297 ,0xd2}, + {0x8298 ,0x01}, + {0x8299 ,0xc2}, + {0x829a ,0x02}, + {0x829b ,0xe4}, + {0x829c ,0xf5}, + {0x829d ,0x1f}, + {0x829e ,0xf5}, + {0x829f ,0x1e}, + {0x82a0 ,0xd2}, + {0x82a1 ,0x35}, + {0x82a2 ,0xd2}, + {0x82a3 ,0x33}, + {0x82a4 ,0xd2}, + {0x82a5 ,0x36}, + {0x82a6 ,0x22}, + {0x82a7 ,0xe5}, + {0x82a8 ,0x1f}, + {0x82a9 ,0x70}, + {0x82aa ,0x72}, + {0x82ab ,0xf5}, + {0x82ac ,0x1e}, + {0x82ad ,0xd2}, + {0x82ae ,0x35}, + {0x82af ,0xff}, + {0x82b0 ,0xef}, + {0x82b1 ,0x25}, + {0x82b2 ,0xe0}, + {0x82b3 ,0x24}, + {0x82b4 ,0x4e}, + {0x82b5 ,0xf8}, + {0x82b6 ,0xe4}, + {0x82b7 ,0xf6}, + {0x82b8 ,0x08}, + {0x82b9 ,0xf6}, + {0x82ba ,0x0f}, + {0x82bb ,0xbf}, + {0x82bc ,0x34}, + {0x82bd ,0xf2}, + {0x82be ,0x90}, + {0x82bf ,0x0e}, + {0x82c0 ,0x94}, + {0x82c1 ,0xe4}, + {0x82c2 ,0x93}, + {0x82c3 ,0xff}, + {0x82c4 ,0xe5}, + {0x82c5 ,0x4b}, + {0x82c6 ,0xc3}, + {0x82c7 ,0x9f}, + {0x82c8 ,0x50}, + {0x82c9 ,0x04}, + {0x82ca ,0x7f}, + {0x82cb ,0x05}, + {0x82cc ,0x80}, + {0x82cd ,0x02}, + {0x82ce ,0x7f}, + {0x82cf ,0xfb}, + {0x82d0 ,0x78}, + {0x82d1 ,0xbd}, + {0x82d2 ,0xa6}, + {0x82d3 ,0x07}, + {0x82d4 ,0x12}, + {0x82d5 ,0x0e}, + {0x82d6 ,0xb1}, + {0x82d7 ,0x40}, + {0x82d8 ,0x04}, + {0x82d9 ,0x7f}, + {0x82da ,0x03}, + {0x82db ,0x80}, + {0x82dc ,0x02}, + {0x82dd ,0x7f}, + {0x82de ,0x30}, + {0x82df ,0x78}, + {0x82e0 ,0xbc}, + {0x82e1 ,0xa6}, + {0x82e2 ,0x07}, + {0x82e3 ,0xe6}, + {0x82e4 ,0x18}, + {0x82e5 ,0xf6}, + {0x82e6 ,0x08}, + {0x82e7 ,0xe6}, + {0x82e8 ,0x78}, + {0x82e9 ,0xb9}, + {0x82ea ,0xf6}, + {0x82eb ,0x78}, + {0x82ec ,0xbc}, + {0x82ed ,0xe6}, + {0x82ee ,0x78}, + {0x82ef ,0xba}, + {0x82f0 ,0xf6}, + {0x82f1 ,0x78}, + {0x82f2 ,0xbf}, + {0x82f3 ,0x76}, + {0x82f4 ,0x33}, + {0x82f5 ,0xe4}, + {0x82f6 ,0x08}, + {0x82f7 ,0xf6}, + {0x82f8 ,0x78}, + {0x82f9 ,0xb8}, + {0x82fa ,0x76}, + {0x82fb ,0x01}, + {0x82fc ,0x75}, + {0x82fd ,0x4a}, + {0x82fe ,0x02}, + {0x82ff ,0x78}, + {0x8300 ,0xb6}, + {0x8301 ,0xf6}, + {0x8302 ,0x08}, + {0x8303 ,0xf6}, + {0x8304 ,0x74}, + {0x8305 ,0xff}, + {0x8306 ,0x78}, + {0x8307 ,0xc1}, + {0x8308 ,0xf6}, + {0x8309 ,0x08}, + {0x830a ,0xf6}, + {0x830b ,0x75}, + {0x830c ,0x1f}, + {0x830d ,0x01}, + {0x830e ,0x78}, + {0x830f ,0xbc}, + {0x8310 ,0xe6}, + {0x8311 ,0x75}, + {0x8312 ,0xf0}, + {0x8313 ,0x05}, + {0x8314 ,0xa4}, + {0x8315 ,0xf5}, + {0x8316 ,0x4b}, + {0x8317 ,0x12}, + {0x8318 ,0x0b}, + {0x8319 ,0x39}, + {0x831a ,0xc2}, + {0x831b ,0x37}, + {0x831c ,0x22}, + {0x831d ,0x78}, + {0x831e ,0xb8}, + {0x831f ,0xe6}, + {0x8320 ,0xd3}, + {0x8321 ,0x94}, + {0x8322 ,0x00}, + {0x8323 ,0x40}, + {0x8324 ,0x02}, + {0x8325 ,0x16}, + {0x8326 ,0x22}, + {0x8327 ,0xe5}, + {0x8328 ,0x1f}, + {0x8329 ,0xb4}, + {0x832a ,0x05}, + {0x832b ,0x23}, + {0x832c ,0xe4}, + {0x832d ,0xf5}, + {0x832e ,0x1f}, + {0x832f ,0xc2}, + {0x8330 ,0x01}, + {0x8331 ,0x78}, + {0x8332 ,0xb6}, + {0x8333 ,0xe6}, + {0x8334 ,0xfe}, + {0x8335 ,0x08}, + {0x8336 ,0xe6}, + {0x8337 ,0xff}, + {0x8338 ,0x78}, + {0x8339 ,0x4e}, + {0x833a ,0xa6}, + {0x833b ,0x06}, + {0x833c ,0x08}, + {0x833d ,0xa6}, + {0x833e ,0x07}, + {0x833f ,0xa2}, + {0x8340 ,0x37}, + {0x8341 ,0xe4}, + {0x8342 ,0x33}, + {0x8343 ,0xf5}, + {0x8344 ,0x3c}, + {0x8345 ,0x90}, + {0x8346 ,0x30}, + {0x8347 ,0x28}, + {0x8348 ,0xf0}, + {0x8349 ,0x75}, + {0x834a ,0x1e}, + {0x834b ,0x10}, + {0x834c ,0xd2}, + {0x834d ,0x35}, + {0x834e ,0x22}, + {0x834f ,0xe5}, + {0x8350 ,0x4b}, + {0x8351 ,0x75}, + {0x8352 ,0xf0}, + {0x8353 ,0x05}, + {0x8354 ,0x84}, + {0x8355 ,0x78}, + {0x8356 ,0xbc}, + {0x8357 ,0xf6}, + {0x8358 ,0x90}, + {0x8359 ,0x0e}, + {0x835a ,0x8c}, + {0x835b ,0xe4}, + {0x835c ,0x93}, + {0x835d ,0xff}, + {0x835e ,0x25}, + {0x835f ,0xe0}, + {0x8360 ,0x24}, + {0x8361 ,0x0a}, + {0x8362 ,0xf8}, + {0x8363 ,0xe6}, + {0x8364 ,0xfc}, + {0x8365 ,0x08}, + {0x8366 ,0xe6}, + {0x8367 ,0xfd}, + {0x8368 ,0x78}, + {0x8369 ,0xbc}, + {0x836a ,0xe6}, + {0x836b ,0x25}, + {0x836c ,0xe0}, + {0x836d ,0x24}, + {0x836e ,0x4e}, + {0x836f ,0xf8}, + {0x8370 ,0xa6}, + {0x8371 ,0x04}, + {0x8372 ,0x08}, + {0x8373 ,0xa6}, + {0x8374 ,0x05}, + {0x8375 ,0xef}, + {0x8376 ,0x12}, + {0x8377 ,0x0e}, + {0x8378 ,0xf5}, + {0x8379 ,0xd3}, + {0x837a ,0x78}, + {0x837b ,0xb7}, + {0x837c ,0x96}, + {0x837d ,0xee}, + {0x837e ,0x18}, + {0x837f ,0x96}, + {0x8380 ,0x40}, + {0x8381 ,0x0d}, + {0x8382 ,0x78}, + {0x8383 ,0xbc}, + {0x8384 ,0xe6}, + {0x8385 ,0x78}, + {0x8386 ,0xb9}, + {0x8387 ,0xf6}, + {0x8388 ,0x78}, + {0x8389 ,0xb6}, + {0x838a ,0xa6}, + {0x838b ,0x06}, + {0x838c ,0x08}, + {0x838d ,0xa6}, + {0x838e ,0x07}, + {0x838f ,0x90}, + {0x8390 ,0x0e}, + {0x8391 ,0x8c}, + {0x8392 ,0xe4}, + {0x8393 ,0x93}, + {0x8394 ,0x12}, + {0x8395 ,0x0e}, + {0x8396 ,0xf5}, + {0x8397 ,0xc3}, + {0x8398 ,0x78}, + {0x8399 ,0xc2}, + {0x839a ,0x96}, + {0x839b ,0xee}, + {0x839c ,0x18}, + {0x839d ,0x96}, + {0x839e ,0x50}, + {0x839f ,0x0d}, + {0x83a0 ,0x78}, + {0x83a1 ,0xbc}, + {0x83a2 ,0xe6}, + {0x83a3 ,0x78}, + {0x83a4 ,0xba}, + {0x83a5 ,0xf6}, + {0x83a6 ,0x78}, + {0x83a7 ,0xc1}, + {0x83a8 ,0xa6}, + {0x83a9 ,0x06}, + {0x83aa ,0x08}, + {0x83ab ,0xa6}, + {0x83ac ,0x07}, + {0x83ad ,0x78}, + {0x83ae ,0xb6}, + {0x83af ,0xe6}, + {0x83b0 ,0xfe}, + {0x83b1 ,0x08}, + {0x83b2 ,0xe6}, + {0x83b3 ,0xc3}, + {0x83b4 ,0x78}, + {0x83b5 ,0xc2}, + {0x83b6 ,0x96}, + {0x83b7 ,0xff}, + {0x83b8 ,0xee}, + {0x83b9 ,0x18}, + {0x83ba ,0x96}, + {0x83bb ,0x78}, + {0x83bc ,0xc3}, + {0x83bd ,0xf6}, + {0x83be ,0x08}, + {0x83bf ,0xa6}, + {0x83c0 ,0x07}, + {0x83c1 ,0x90}, + {0x83c2 ,0x0e}, + {0x83c3 ,0x96}, + {0x83c4 ,0xe4}, + {0x83c5 ,0x18}, + {0x83c6 ,0x12}, + {0x83c7 ,0x0e}, + {0x83c8 ,0xb8}, + {0x83c9 ,0x40}, + {0x83ca ,0x02}, + {0x83cb ,0xd2}, + {0x83cc ,0x37}, + {0x83cd ,0x78}, + {0x83ce ,0xbc}, + {0x83cf ,0xe6}, + {0x83d0 ,0x08}, + {0x83d1 ,0x26}, + {0x83d2 ,0x08}, + {0x83d3 ,0xf6}, + {0x83d4 ,0xe5}, + {0x83d5 ,0x1f}, + {0x83d6 ,0x64}, + {0x83d7 ,0x01}, + {0x83d8 ,0x70}, + {0x83d9 ,0x7a}, + {0x83da ,0xe6}, + {0x83db ,0xc3}, + {0x83dc ,0x78}, + {0x83dd ,0xc0}, + {0x83de ,0x12}, + {0x83df ,0x0e}, + {0x83e0 ,0xa1}, + {0x83e1 ,0x40}, + {0x83e2 ,0x08}, + {0x83e3 ,0x12}, + {0x83e4 ,0x0e}, + {0x83e5 ,0x9c}, + {0x83e6 ,0x50}, + {0x83e7 ,0x03}, + {0x83e8 ,0x02}, + {0x83e9 ,0x04}, + {0x83ea ,0xf1}, + {0x83eb ,0x12}, + {0x83ec ,0x0e}, + {0x83ed ,0xaf}, + {0x83ee ,0x40}, + {0x83ef ,0x04}, + {0x83f0 ,0x7f}, + {0x83f1 ,0xfe}, + {0x83f2 ,0x80}, + {0x83f3 ,0x02}, + {0x83f4 ,0x7f}, + {0x83f5 ,0x02}, + {0x83f6 ,0x78}, + {0x83f7 ,0xbd}, + {0x83f8 ,0xa6}, + {0x83f9 ,0x07}, + {0x83fa ,0x78}, + {0x83fb ,0xb9}, + {0x83fc ,0xe6}, + {0x83fd ,0x24}, + {0x83fe ,0x03}, + {0x83ff ,0x78}, + {0x8400 ,0xbf}, + {0x8401 ,0xf6}, + {0x8402 ,0x78}, + {0x8403 ,0xb9}, + {0x8404 ,0xe6}, + {0x8405 ,0x24}, + {0x8406 ,0xfd}, + {0x8407 ,0x78}, + {0x8408 ,0xc0}, + {0x8409 ,0xf6}, + {0x840a ,0x18}, + {0x840b ,0x12}, + {0x840c ,0x0e}, + {0x840d ,0xb1}, + {0x840e ,0x40}, + {0x840f ,0x04}, + {0x8410 ,0xe6}, + {0x8411 ,0xff}, + {0x8412 ,0x80}, + {0x8413 ,0x02}, + {0x8414 ,0x7f}, + {0x8415 ,0x00}, + {0x8416 ,0x12}, + {0x8417 ,0x0e}, + {0x8418 ,0xd1}, + {0x8419 ,0x40}, + {0x841a ,0x04}, + {0x841b ,0xe6}, + {0x841c ,0xff}, + {0x841d ,0x80}, + {0x841e ,0x02}, + {0x841f ,0x7f}, + {0x8420 ,0x00}, + {0x8421 ,0x12}, + {0x8422 ,0x0e}, + {0x8423 ,0xdd}, + {0x8424 ,0x50}, + {0x8425 ,0x04}, + {0x8426 ,0xe6}, + {0x8427 ,0xff}, + {0x8428 ,0x80}, + {0x8429 ,0x02}, + {0x842a ,0x7f}, + {0x842b ,0x33}, + {0x842c ,0x12}, + {0x842d ,0x0e}, + {0x842e ,0xe9}, + {0x842f ,0x50}, + {0x8430 ,0x04}, + {0x8431 ,0xe6}, + {0x8432 ,0xff}, + {0x8433 ,0x80}, + {0x8434 ,0x02}, + {0x8435 ,0x7f}, + {0x8436 ,0x33}, + {0x8437 ,0x12}, + {0x8438 ,0x0e}, + {0x8439 ,0xab}, + {0x843a ,0x40}, + {0x843b ,0x06}, + {0x843c ,0x78}, + {0x843d ,0xc0}, + {0x843e ,0xe6}, + {0x843f ,0xff}, + {0x8440 ,0x80}, + {0x8441 ,0x04}, + {0x8442 ,0x78}, + {0x8443 ,0xbf}, + {0x8444 ,0xe6}, + {0x8445 ,0xff}, + {0x8446 ,0x78}, + {0x8447 ,0xbe}, + {0x8448 ,0xa6}, + {0x8449 ,0x07}, + {0x844a ,0x75}, + {0x844b ,0x1f}, + {0x844c ,0x02}, + {0x844d ,0x78}, + {0x844e ,0xb8}, + {0x844f ,0x76}, + {0x8450 ,0x01}, + {0x8451 ,0x02}, + {0x8452 ,0x04}, + {0x8453 ,0xf1}, + {0x8454 ,0xe5}, + {0x8455 ,0x1f}, + {0x8456 ,0x64}, + {0x8457 ,0x02}, + {0x8458 ,0x70}, + {0x8459 ,0x77}, + {0x845a ,0x78}, + {0x845b ,0xbe}, + {0x845c ,0xe6}, + {0x845d ,0xff}, + {0x845e ,0xc3}, + {0x845f ,0x78}, + {0x8460 ,0xc0}, + {0x8461 ,0x12}, + {0x8462 ,0x0e}, + {0x8463 ,0xa2}, + {0x8464 ,0x40}, + {0x8465 ,0x05}, + {0x8466 ,0x12}, + {0x8467 ,0x0e}, + {0x8468 ,0x9c}, + {0x8469 ,0x40}, + {0x846a ,0x64}, + {0x846b ,0x12}, + {0x846c ,0x0e}, + {0x846d ,0xaf}, + {0x846e ,0x40}, + {0x846f ,0x04}, + {0x8470 ,0x7f}, + {0x8471 ,0xff}, + {0x8472 ,0x80}, + {0x8473 ,0x02}, + {0x8474 ,0x7f}, + {0x8475 ,0x01}, + {0x8476 ,0x78}, + {0x8477 ,0xbd}, + {0x8478 ,0xa6}, + {0x8479 ,0x07}, + {0x847a ,0x78}, + {0x847b ,0xb9}, + {0x847c ,0xe6}, + {0x847d ,0x04}, + {0x847e ,0x78}, + {0x847f ,0xbf}, + {0x8480 ,0xf6}, + {0x8481 ,0x78}, + {0x8482 ,0xb9}, + {0x8483 ,0xe6}, + {0x8484 ,0x14}, + {0x8485 ,0x78}, + {0x8486 ,0xc0}, + {0x8487 ,0xf6}, + {0x8488 ,0x18}, + {0x8489 ,0x12}, + {0x848a ,0x0e}, + {0x848b ,0xd6}, + {0x848c ,0x40}, + {0x848d ,0x04}, + {0x848e ,0xe6}, + {0x848f ,0xff}, + {0x8490 ,0x80}, + {0x8491 ,0x02}, + {0x8492 ,0x7f}, + {0x8493 ,0x00}, + {0x8494 ,0x12}, + {0x8495 ,0x0e}, + {0x8496 ,0xd1}, + {0x8497 ,0x40}, + {0x8498 ,0x04}, + {0x8499 ,0xe6}, + {0x849a ,0xff}, + {0x849b ,0x80}, + {0x849c ,0x02}, + {0x849d ,0x7f}, + {0x849e ,0x00}, + {0x849f ,0x12}, + {0x84a0 ,0x0e}, + {0x84a1 ,0xdd}, + {0x84a2 ,0x50}, + {0x84a3 ,0x04}, + {0x84a4 ,0xe6}, + {0x84a5 ,0xff}, + {0x84a6 ,0x80}, + {0x84a7 ,0x02}, + {0x84a8 ,0x7f}, + {0x84a9 ,0x33}, + {0x84aa ,0x12}, + {0x84ab ,0x0e}, + {0x84ac ,0xe9}, + {0x84ad ,0x50}, + {0x84ae ,0x04}, + {0x84af ,0xe6}, + {0x84b0 ,0xff}, + {0x84b1 ,0x80}, + {0x84b2 ,0x02}, + {0x84b3 ,0x7f}, + {0x84b4 ,0x33}, + {0x84b5 ,0x12}, + {0x84b6 ,0x0e}, + {0x84b7 ,0xab}, + {0x84b8 ,0x40}, + {0x84b9 ,0x06}, + {0x84ba ,0x78}, + {0x84bb ,0xc0}, + {0x84bc ,0xe6}, + {0x84bd ,0xff}, + {0x84be ,0x80}, + {0x84bf ,0x04}, + {0x84c0 ,0x78}, + {0x84c1 ,0xbf}, + {0x84c2 ,0xe6}, + {0x84c3 ,0xff}, + {0x84c4 ,0x78}, + {0x84c5 ,0xbe}, + {0x84c6 ,0xa6}, + {0x84c7 ,0x07}, + {0x84c8 ,0x75}, + {0x84c9 ,0x1f}, + {0x84ca ,0x03}, + {0x84cb ,0x78}, + {0x84cc ,0xb8}, + {0x84cd ,0x76}, + {0x84ce ,0x01}, + {0x84cf ,0x80}, + {0x84d0 ,0x20}, + {0x84d1 ,0xe5}, + {0x84d2 ,0x1f}, + {0x84d3 ,0x64}, + {0x84d4 ,0x03}, + {0x84d5 ,0x70}, + {0x84d6 ,0x26}, + {0x84d7 ,0x78}, + {0x84d8 ,0xbe}, + {0x84d9 ,0xe6}, + {0x84da ,0xff}, + {0x84db ,0xc3}, + {0x84dc ,0x78}, + {0x84dd ,0xc0}, + {0x84de ,0x12}, + {0x84df ,0x0e}, + {0x84e0 ,0xa2}, + {0x84e1 ,0x40}, + {0x84e2 ,0x05}, + {0x84e3 ,0x12}, + {0x84e4 ,0x0e}, + {0x84e5 ,0x9c}, + {0x84e6 ,0x40}, + {0x84e7 ,0x09}, + {0x84e8 ,0x78}, + {0x84e9 ,0xb9}, + {0x84ea ,0xe6}, + {0x84eb ,0x78}, + {0x84ec ,0xbe}, + {0x84ed ,0xf6}, + {0x84ee ,0x75}, + {0x84ef ,0x1f}, + {0x84f0 ,0x04}, + {0x84f1 ,0x78}, + {0x84f2 ,0xbe}, + {0x84f3 ,0xe6}, + {0x84f4 ,0x75}, + {0x84f5 ,0xf0}, + {0x84f6 ,0x05}, + {0x84f7 ,0xa4}, + {0x84f8 ,0xf5}, + {0x84f9 ,0x4b}, + {0x84fa ,0x02}, + {0x84fb ,0x0b}, + {0x84fc ,0x39}, + {0x84fd ,0xe5}, + {0x84fe ,0x1f}, + {0x84ff ,0x64}, + {0x8500 ,0x04}, + {0x8501 ,0x70}, + {0x8502 ,0x1e}, + {0x8503 ,0x90}, + {0x8504 ,0x0e}, + {0x8505 ,0x95}, + {0x8506 ,0x78}, + {0x8507 ,0xc3}, + {0x8508 ,0x12}, + {0x8509 ,0x0e}, + {0x850a ,0xb8}, + {0x850b ,0x40}, + {0x850c ,0x04}, + {0x850d ,0xd2}, + {0x850e ,0x37}, + {0x850f ,0x80}, + {0x8510 ,0x0d}, + {0x8511 ,0x90}, + {0x8512 ,0x0e}, + {0x8513 ,0x97}, + {0x8514 ,0xe4}, + {0x8515 ,0x93}, + {0x8516 ,0xff}, + {0x8517 ,0x60}, + {0x8518 ,0x05}, + {0x8519 ,0xf5}, + {0x851a ,0x4b}, + {0x851b ,0x12}, + {0x851c ,0x0b}, + {0x851d ,0x39}, + {0x851e ,0x75}, + {0x851f ,0x1f}, + {0x8520 ,0x05}, + {0x8521 ,0x22}, + {0x8522 ,0xef}, + {0x8523 ,0x8d}, + {0x8524 ,0xf0}, + {0x8525 ,0xa4}, + {0x8526 ,0xa8}, + {0x8527 ,0xf0}, + {0x8528 ,0xcf}, + {0x8529 ,0x8c}, + {0x852a ,0xf0}, + {0x852b ,0xa4}, + {0x852c ,0x28}, + {0x852d ,0xce}, + {0x852e ,0x8d}, + {0x852f ,0xf0}, + {0x8530 ,0xa4}, + {0x8531 ,0x2e}, + {0x8532 ,0xfe}, + {0x8533 ,0x22}, + {0x8534 ,0xbc}, + {0x8535 ,0x00}, + {0x8536 ,0x0b}, + {0x8537 ,0xbe}, + {0x8538 ,0x00}, + {0x8539 ,0x29}, + {0x853a ,0xef}, + {0x853b ,0x8d}, + {0x853c ,0xf0}, + {0x853d ,0x84}, + {0x853e ,0xff}, + {0x853f ,0xad}, + {0x8540 ,0xf0}, + {0x8541 ,0x22}, + {0x8542 ,0xe4}, + {0x8543 ,0xcc}, + {0x8544 ,0xf8}, + {0x8545 ,0x75}, + {0x8546 ,0xf0}, + {0x8547 ,0x08}, + {0x8548 ,0xef}, + {0x8549 ,0x2f}, + {0x854a ,0xff}, + {0x854b ,0xee}, + {0x854c ,0x33}, + {0x854d ,0xfe}, + {0x854e ,0xec}, + {0x854f ,0x33}, + {0x8550 ,0xfc}, + {0x8551 ,0xee}, + {0x8552 ,0x9d}, + {0x8553 ,0xec}, + {0x8554 ,0x98}, + {0x8555 ,0x40}, + {0x8556 ,0x05}, + {0x8557 ,0xfc}, + {0x8558 ,0xee}, + {0x8559 ,0x9d}, + {0x855a ,0xfe}, + {0x855b ,0x0f}, + {0x855c ,0xd5}, + {0x855d ,0xf0}, + {0x855e ,0xe9}, + {0x855f ,0xe4}, + {0x8560 ,0xce}, + {0x8561 ,0xfd}, + {0x8562 ,0x22}, + {0x8563 ,0xed}, + {0x8564 ,0xf8}, + {0x8565 ,0xf5}, + {0x8566 ,0xf0}, + {0x8567 ,0xee}, + {0x8568 ,0x84}, + {0x8569 ,0x20}, + {0x856a ,0xd2}, + {0x856b ,0x1c}, + {0x856c ,0xfe}, + {0x856d ,0xad}, + {0x856e ,0xf0}, + {0x856f ,0x75}, + {0x8570 ,0xf0}, + {0x8571 ,0x08}, + {0x8572 ,0xef}, + {0x8573 ,0x2f}, + {0x8574 ,0xff}, + {0x8575 ,0xed}, + {0x8576 ,0x33}, + {0x8577 ,0xfd}, + {0x8578 ,0x40}, + {0x8579 ,0x07}, + {0x857a ,0x98}, + {0x857b ,0x50}, + {0x857c ,0x06}, + {0x857d ,0xd5}, + {0x857e ,0xf0}, + {0x857f ,0xf2}, + {0x8580 ,0x22}, + {0x8581 ,0xc3}, + {0x8582 ,0x98}, + {0x8583 ,0xfd}, + {0x8584 ,0x0f}, + {0x8585 ,0xd5}, + {0x8586 ,0xf0}, + {0x8587 ,0xea}, + {0x8588 ,0x22}, + {0x8589 ,0xe8}, + {0x858a ,0x8f}, + {0x858b ,0xf0}, + {0x858c ,0xa4}, + {0x858d ,0xcc}, + {0x858e ,0x8b}, + {0x858f ,0xf0}, + {0x8590 ,0xa4}, + {0x8591 ,0x2c}, + {0x8592 ,0xfc}, + {0x8593 ,0xe9}, + {0x8594 ,0x8e}, + {0x8595 ,0xf0}, + {0x8596 ,0xa4}, + {0x8597 ,0x2c}, + {0x8598 ,0xfc}, + {0x8599 ,0x8a}, + {0x859a ,0xf0}, + {0x859b ,0xed}, + {0x859c ,0xa4}, + {0x859d ,0x2c}, + {0x859e ,0xfc}, + {0x859f ,0xea}, + {0x85a0 ,0x8e}, + {0x85a1 ,0xf0}, + {0x85a2 ,0xa4}, + {0x85a3 ,0xcd}, + {0x85a4 ,0xa8}, + {0x85a5 ,0xf0}, + {0x85a6 ,0x8b}, + {0x85a7 ,0xf0}, + {0x85a8 ,0xa4}, + {0x85a9 ,0x2d}, + {0x85aa ,0xcc}, + {0x85ab ,0x38}, + {0x85ac ,0x25}, + {0x85ad ,0xf0}, + {0x85ae ,0xfd}, + {0x85af ,0xe9}, + {0x85b0 ,0x8f}, + {0x85b1 ,0xf0}, + {0x85b2 ,0xa4}, + {0x85b3 ,0x2c}, + {0x85b4 ,0xcd}, + {0x85b5 ,0x35}, + {0x85b6 ,0xf0}, + {0x85b7 ,0xfc}, + {0x85b8 ,0xeb}, + {0x85b9 ,0x8e}, + {0x85ba ,0xf0}, + {0x85bb ,0xa4}, + {0x85bc ,0xfe}, + {0x85bd ,0xa9}, + {0x85be ,0xf0}, + {0x85bf ,0xeb}, + {0x85c0 ,0x8f}, + {0x85c1 ,0xf0}, + {0x85c2 ,0xa4}, + {0x85c3 ,0xcf}, + {0x85c4 ,0xc5}, + {0x85c5 ,0xf0}, + {0x85c6 ,0x2e}, + {0x85c7 ,0xcd}, + {0x85c8 ,0x39}, + {0x85c9 ,0xfe}, + {0x85ca ,0xe4}, + {0x85cb ,0x3c}, + {0x85cc ,0xfc}, + {0x85cd ,0xea}, + {0x85ce ,0xa4}, + {0x85cf ,0x2d}, + {0x85d0 ,0xce}, + {0x85d1 ,0x35}, + {0x85d2 ,0xf0}, + {0x85d3 ,0xfd}, + {0x85d4 ,0xe4}, + {0x85d5 ,0x3c}, + {0x85d6 ,0xfc}, + {0x85d7 ,0x22}, + {0x85d8 ,0x75}, + {0x85d9 ,0xf0}, + {0x85da ,0x08}, + {0x85db ,0x75}, + {0x85dc ,0x82}, + {0x85dd ,0x00}, + {0x85de ,0xef}, + {0x85df ,0x2f}, + {0x85e0 ,0xff}, + {0x85e1 ,0xee}, + {0x85e2 ,0x33}, + {0x85e3 ,0xfe}, + {0x85e4 ,0xcd}, + {0x85e5 ,0x33}, + {0x85e6 ,0xcd}, + {0x85e7 ,0xcc}, + {0x85e8 ,0x33}, + {0x85e9 ,0xcc}, + {0x85ea ,0xc5}, + {0x85eb ,0x82}, + {0x85ec ,0x33}, + {0x85ed ,0xc5}, + {0x85ee ,0x82}, + {0x85ef ,0x9b}, + {0x85f0 ,0xed}, + {0x85f1 ,0x9a}, + {0x85f2 ,0xec}, + {0x85f3 ,0x99}, + {0x85f4 ,0xe5}, + {0x85f5 ,0x82}, + {0x85f6 ,0x98}, + {0x85f7 ,0x40}, + {0x85f8 ,0x0c}, + {0x85f9 ,0xf5}, + {0x85fa ,0x82}, + {0x85fb ,0xee}, + {0x85fc ,0x9b}, + {0x85fd ,0xfe}, + {0x85fe ,0xed}, + {0x85ff ,0x9a}, + {0x8600 ,0xfd}, + {0x8601 ,0xec}, + {0x8602 ,0x99}, + {0x8603 ,0xfc}, + {0x8604 ,0x0f}, + {0x8605 ,0xd5}, + {0x8606 ,0xf0}, + {0x8607 ,0xd6}, + {0x8608 ,0xe4}, + {0x8609 ,0xce}, + {0x860a ,0xfb}, + {0x860b ,0xe4}, + {0x860c ,0xcd}, + {0x860d ,0xfa}, + {0x860e ,0xe4}, + {0x860f ,0xcc}, + {0x8610 ,0xf9}, + {0x8611 ,0xa8}, + {0x8612 ,0x82}, + {0x8613 ,0x22}, + {0x8614 ,0xb8}, + {0x8615 ,0x00}, + {0x8616 ,0xc1}, + {0x8617 ,0xb9}, + {0x8618 ,0x00}, + {0x8619 ,0x59}, + {0x861a ,0xba}, + {0x861b ,0x00}, + {0x861c ,0x2d}, + {0x861d ,0xec}, + {0x861e ,0x8b}, + {0x861f ,0xf0}, + {0x8620 ,0x84}, + {0x8621 ,0xcf}, + {0x8622 ,0xce}, + {0x8623 ,0xcd}, + {0x8624 ,0xfc}, + {0x8625 ,0xe5}, + {0x8626 ,0xf0}, + {0x8627 ,0xcb}, + {0x8628 ,0xf9}, + {0x8629 ,0x78}, + {0x862a ,0x18}, + {0x862b ,0xef}, + {0x862c ,0x2f}, + {0x862d ,0xff}, + {0x862e ,0xee}, + {0x862f ,0x33}, + {0x8630 ,0xfe}, + {0x8631 ,0xed}, + {0x8632 ,0x33}, + {0x8633 ,0xfd}, + {0x8634 ,0xec}, + {0x8635 ,0x33}, + {0x8636 ,0xfc}, + {0x8637 ,0xeb}, + {0x8638 ,0x33}, + {0x8639 ,0xfb}, + {0x863a ,0x10}, + {0x863b ,0xd7}, + {0x863c ,0x03}, + {0x863d ,0x99}, + {0x863e ,0x40}, + {0x863f ,0x04}, + {0x8640 ,0xeb}, + {0x8641 ,0x99}, + {0x8642 ,0xfb}, + {0x8643 ,0x0f}, + {0x8644 ,0xd8}, + {0x8645 ,0xe5}, + {0x8646 ,0xe4}, + {0x8647 ,0xf9}, + {0x8648 ,0xfa}, + {0x8649 ,0x22}, + {0x864a ,0x78}, + {0x864b ,0x18}, + {0x864c ,0xef}, + {0x864d ,0x2f}, + {0x864e ,0xff}, + {0x864f ,0xee}, + {0x8650 ,0x33}, + {0x8651 ,0xfe}, + {0x8652 ,0xed}, + {0x8653 ,0x33}, + {0x8654 ,0xfd}, + {0x8655 ,0xec}, + {0x8656 ,0x33}, + {0x8657 ,0xfc}, + {0x8658 ,0xc9}, + {0x8659 ,0x33}, + {0x865a ,0xc9}, + {0x865b ,0x10}, + {0x865c ,0xd7}, + {0x865d ,0x05}, + {0x865e ,0x9b}, + {0x865f ,0xe9}, + {0x8660 ,0x9a}, + {0x8661 ,0x40}, + {0x8662 ,0x07}, + {0x8663 ,0xec}, + {0x8664 ,0x9b}, + {0x8665 ,0xfc}, + {0x8666 ,0xe9}, + {0x8667 ,0x9a}, + {0x8668 ,0xf9}, + {0x8669 ,0x0f}, + {0x866a ,0xd8}, + {0x866b ,0xe0}, + {0x866c ,0xe4}, + {0x866d ,0xc9}, + {0x866e ,0xfa}, + {0x866f ,0xe4}, + {0x8670 ,0xcc}, + {0x8671 ,0xfb}, + {0x8672 ,0x22}, + {0x8673 ,0x75}, + {0x8674 ,0xf0}, + {0x8675 ,0x10}, + {0x8676 ,0xef}, + {0x8677 ,0x2f}, + {0x8678 ,0xff}, + {0x8679 ,0xee}, + {0x867a ,0x33}, + {0x867b ,0xfe}, + {0x867c ,0xed}, + {0x867d ,0x33}, + {0x867e ,0xfd}, + {0x867f ,0xcc}, + {0x8680 ,0x33}, + {0x8681 ,0xcc}, + {0x8682 ,0xc8}, + {0x8683 ,0x33}, + {0x8684 ,0xc8}, + {0x8685 ,0x10}, + {0x8686 ,0xd7}, + {0x8687 ,0x07}, + {0x8688 ,0x9b}, + {0x8689 ,0xec}, + {0x868a ,0x9a}, + {0x868b ,0xe8}, + {0x868c ,0x99}, + {0x868d ,0x40}, + {0x868e ,0x0a}, + {0x868f ,0xed}, + {0x8690 ,0x9b}, + {0x8691 ,0xfd}, + {0x8692 ,0xec}, + {0x8693 ,0x9a}, + {0x8694 ,0xfc}, + {0x8695 ,0xe8}, + {0x8696 ,0x99}, + {0x8697 ,0xf8}, + {0x8698 ,0x0f}, + {0x8699 ,0xd5}, + {0x869a ,0xf0}, + {0x869b ,0xda}, + {0x869c ,0xe4}, + {0x869d ,0xcd}, + {0x869e ,0xfb}, + {0x869f ,0xe4}, + {0x86a0 ,0xcc}, + {0x86a1 ,0xfa}, + {0x86a2 ,0xe4}, + {0x86a3 ,0xc8}, + {0x86a4 ,0xf9}, + {0x86a5 ,0x22}, + {0x86a6 ,0xeb}, + {0x86a7 ,0x9f}, + {0x86a8 ,0xf5}, + {0x86a9 ,0xf0}, + {0x86aa ,0xea}, + {0x86ab ,0x9e}, + {0x86ac ,0x42}, + {0x86ad ,0xf0}, + {0x86ae ,0xe9}, + {0x86af ,0x9d}, + {0x86b0 ,0x42}, + {0x86b1 ,0xf0}, + {0x86b2 ,0xe8}, + {0x86b3 ,0x9c}, + {0x86b4 ,0x45}, + {0x86b5 ,0xf0}, + {0x86b6 ,0x22}, + {0x86b7 ,0xe8}, + {0x86b8 ,0x60}, + {0x86b9 ,0x0f}, + {0x86ba ,0xec}, + {0x86bb ,0xc3}, + {0x86bc ,0x13}, + {0x86bd ,0xfc}, + {0x86be ,0xed}, + {0x86bf ,0x13}, + {0x86c0 ,0xfd}, + {0x86c1 ,0xee}, + {0x86c2 ,0x13}, + {0x86c3 ,0xfe}, + {0x86c4 ,0xef}, + {0x86c5 ,0x13}, + {0x86c6 ,0xff}, + {0x86c7 ,0xd8}, + {0x86c8 ,0xf1}, + {0x86c9 ,0x22}, + {0x86ca ,0xe8}, + {0x86cb ,0x60}, + {0x86cc ,0x0f}, + {0x86cd ,0xef}, + {0x86ce ,0xc3}, + {0x86cf ,0x33}, + {0x86d0 ,0xff}, + {0x86d1 ,0xee}, + {0x86d2 ,0x33}, + {0x86d3 ,0xfe}, + {0x86d4 ,0xed}, + {0x86d5 ,0x33}, + {0x86d6 ,0xfd}, + {0x86d7 ,0xec}, + {0x86d8 ,0x33}, + {0x86d9 ,0xfc}, + {0x86da ,0xd8}, + {0x86db ,0xf1}, + {0x86dc ,0x22}, + {0x86dd ,0xe4}, + {0x86de ,0x93}, + {0x86df ,0xfc}, + {0x86e0 ,0x74}, + {0x86e1 ,0x01}, + {0x86e2 ,0x93}, + {0x86e3 ,0xfd}, + {0x86e4 ,0x74}, + {0x86e5 ,0x02}, + {0x86e6 ,0x93}, + {0x86e7 ,0xfe}, + {0x86e8 ,0x74}, + {0x86e9 ,0x03}, + {0x86ea ,0x93}, + {0x86eb ,0xff}, + {0x86ec ,0x22}, + {0x86ed ,0xe6}, + {0x86ee ,0xfb}, + {0x86ef ,0x08}, + {0x86f0 ,0xe6}, + {0x86f1 ,0xf9}, + {0x86f2 ,0x08}, + {0x86f3 ,0xe6}, + {0x86f4 ,0xfa}, + {0x86f5 ,0x08}, + {0x86f6 ,0xe6}, + {0x86f7 ,0xcb}, + {0x86f8 ,0xf8}, + {0x86f9 ,0x22}, + {0x86fa ,0xec}, + {0x86fb ,0xf6}, + {0x86fc ,0x08}, + {0x86fd ,0xed}, + {0x86fe ,0xf6}, + {0x86ff ,0x08}, + {0x8700 ,0xee}, + {0x8701 ,0xf6}, + {0x8702 ,0x08}, + {0x8703 ,0xef}, + {0x8704 ,0xf6}, + {0x8705 ,0x22}, + {0x8706 ,0xa4}, + {0x8707 ,0x25}, + {0x8708 ,0x82}, + {0x8709 ,0xf5}, + {0x870a ,0x82}, + {0x870b ,0xe5}, + {0x870c ,0xf0}, + {0x870d ,0x35}, + {0x870e ,0x83}, + {0x870f ,0xf5}, + {0x8710 ,0x83}, + {0x8711 ,0x22}, + {0x8712 ,0xd0}, + {0x8713 ,0x83}, + {0x8714 ,0xd0}, + {0x8715 ,0x82}, + {0x8716 ,0xf8}, + {0x8717 ,0xe4}, + {0x8718 ,0x93}, + {0x8719 ,0x70}, + {0x871a ,0x12}, + {0x871b ,0x74}, + {0x871c ,0x01}, + {0x871d ,0x93}, + {0x871e ,0x70}, + {0x871f ,0x0d}, + {0x8720 ,0xa3}, + {0x8721 ,0xa3}, + {0x8722 ,0x93}, + {0x8723 ,0xf8}, + {0x8724 ,0x74}, + {0x8725 ,0x01}, + {0x8726 ,0x93}, + {0x8727 ,0xf5}, + {0x8728 ,0x82}, + {0x8729 ,0x88}, + {0x872a ,0x83}, + {0x872b ,0xe4}, + {0x872c ,0x73}, + {0x872d ,0x74}, + {0x872e ,0x02}, + {0x872f ,0x93}, + {0x8730 ,0x68}, + {0x8731 ,0x60}, + {0x8732 ,0xef}, + {0x8733 ,0xa3}, + {0x8734 ,0xa3}, + {0x8735 ,0xa3}, + {0x8736 ,0x80}, + {0x8737 ,0xdf}, + {0x8738 ,0x90}, + {0x8739 ,0x38}, + {0x873a ,0x04}, + {0x873b ,0x78}, + {0x873c ,0x52}, + {0x873d ,0x12}, + {0x873e ,0x0b}, + {0x873f ,0x0f}, + {0x8740 ,0x90}, + {0x8741 ,0x38}, + {0x8742 ,0x00}, + {0x8743 ,0xe0}, + {0x8744 ,0xfe}, + {0x8745 ,0xa3}, + {0x8746 ,0xe0}, + {0x8747 ,0xfd}, + {0x8748 ,0xed}, + {0x8749 ,0xff}, + {0x874a ,0xc3}, + {0x874b ,0x12}, + {0x874c ,0x0a}, + {0x874d ,0xb0}, + {0x874e ,0x90}, + {0x874f ,0x38}, + {0x8750 ,0x10}, + {0x8751 ,0x12}, + {0x8752 ,0x0a}, + {0x8753 ,0xa4}, + {0x8754 ,0x90}, + {0x8755 ,0x38}, + {0x8756 ,0x06}, + {0x8757 ,0x78}, + {0x8758 ,0x54}, + {0x8759 ,0x12}, + {0x875a ,0x0b}, + {0x875b ,0x0f}, + {0x875c ,0x90}, + {0x875d ,0x38}, + {0x875e ,0x02}, + {0x875f ,0xe0}, + {0x8760 ,0xfe}, + {0x8761 ,0xa3}, + {0x8762 ,0xe0}, + {0x8763 ,0xfd}, + {0x8764 ,0xed}, + {0x8765 ,0xff}, + {0x8766 ,0xc3}, + {0x8767 ,0x12}, + {0x8768 ,0x0a}, + {0x8769 ,0xb0}, + {0x876a ,0x90}, + {0x876b ,0x38}, + {0x876c ,0x12}, + {0x876d ,0x12}, + {0x876e ,0x0a}, + {0x876f ,0xa4}, + {0x8770 ,0xa3}, + {0x8771 ,0xe0}, + {0x8772 ,0xb4}, + {0x8773 ,0x31}, + {0x8774 ,0x07}, + {0x8775 ,0x78}, + {0x8776 ,0x52}, + {0x8777 ,0x79}, + {0x8778 ,0x52}, + {0x8779 ,0x12}, + {0x877a ,0x0b}, + {0x877b ,0x2f}, + {0x877c ,0x90}, + {0x877d ,0x38}, + {0x877e ,0x14}, + {0x877f ,0xe0}, + {0x8780 ,0xb4}, + {0x8781 ,0x71}, + {0x8782 ,0x15}, + {0x8783 ,0x78}, + {0x8784 ,0x52}, + {0x8785 ,0xe6}, + {0x8786 ,0xfe}, + {0x8787 ,0x08}, + {0x8788 ,0xe6}, + {0x8789 ,0x78}, + {0x878a ,0x02}, + {0x878b ,0xce}, + {0x878c ,0xc3}, + {0x878d ,0x13}, + {0x878e ,0xce}, + {0x878f ,0x13}, + {0x8790 ,0xd8}, + {0x8791 ,0xf9}, + {0x8792 ,0x79}, + {0x8793 ,0x53}, + {0x8794 ,0xf7}, + {0x8795 ,0xee}, + {0x8796 ,0x19}, + {0x8797 ,0xf7}, + {0x8798 ,0x90}, + {0x8799 ,0x38}, + {0x879a ,0x15}, + {0x879b ,0xe0}, + {0x879c ,0xb4}, + {0x879d ,0x31}, + {0x879e ,0x07}, + {0x879f ,0x78}, + {0x87a0 ,0x54}, + {0x87a1 ,0x79}, + {0x87a2 ,0x54}, + {0x87a3 ,0x12}, + {0x87a4 ,0x0b}, + {0x87a5 ,0x2f}, + {0x87a6 ,0x90}, + {0x87a7 ,0x38}, + {0x87a8 ,0x15}, + {0x87a9 ,0xe0}, + {0x87aa ,0xb4}, + {0x87ab ,0x71}, + {0x87ac ,0x15}, + {0x87ad ,0x78}, + {0x87ae ,0x54}, + {0x87af ,0xe6}, + {0x87b0 ,0xfe}, + {0x87b1 ,0x08}, + {0x87b2 ,0xe6}, + {0x87b3 ,0x78}, + {0x87b4 ,0x02}, + {0x87b5 ,0xce}, + {0x87b6 ,0xc3}, + {0x87b7 ,0x13}, + {0x87b8 ,0xce}, + {0x87b9 ,0x13}, + {0x87ba ,0xd8}, + {0x87bb ,0xf9}, + {0x87bc ,0x79}, + {0x87bd ,0x55}, + {0x87be ,0xf7}, + {0x87bf ,0xee}, + {0x87c0 ,0x19}, + {0x87c1 ,0xf7}, + {0x87c2 ,0x79}, + {0x87c3 ,0x52}, + {0x87c4 ,0x12}, + {0x87c5 ,0x0a}, + {0x87c6 ,0xeb}, + {0x87c7 ,0x09}, + {0x87c8 ,0x12}, + {0x87c9 ,0x0a}, + {0x87ca ,0xeb}, + {0x87cb ,0xaf}, + {0x87cc ,0x47}, + {0x87cd ,0x12}, + {0x87ce ,0x0a}, + {0x87cf ,0xc4}, + {0x87d0 ,0xe5}, + {0x87d1 ,0x44}, + {0x87d2 ,0xfb}, + {0x87d3 ,0x7a}, + {0x87d4 ,0x00}, + {0x87d5 ,0xfd}, + {0x87d6 ,0x7c}, + {0x87d7 ,0x00}, + {0x87d8 ,0x12}, + {0x87d9 ,0x05}, + {0x87da ,0x34}, + {0x87db ,0x78}, + {0x87dc ,0x5a}, + {0x87dd ,0xa6}, + {0x87de ,0x06}, + {0x87df ,0x08}, + {0x87e0 ,0xa6}, + {0x87e1 ,0x07}, + {0x87e2 ,0xaf}, + {0x87e3 ,0x45}, + {0x87e4 ,0x12}, + {0x87e5 ,0x0a}, + {0x87e6 ,0xc4}, + {0x87e7 ,0xad}, + {0x87e8 ,0x03}, + {0x87e9 ,0x7c}, + {0x87ea ,0x00}, + {0x87eb ,0x12}, + {0x87ec ,0x05}, + {0x87ed ,0x34}, + {0x87ee ,0x78}, + {0x87ef ,0x56}, + {0x87f0 ,0xa6}, + {0x87f1 ,0x06}, + {0x87f2 ,0x08}, + {0x87f3 ,0xa6}, + {0x87f4 ,0x07}, + {0x87f5 ,0xaf}, + {0x87f6 ,0x48}, + {0x87f7 ,0x78}, + {0x87f8 ,0x54}, + {0x87f9 ,0x12}, + {0x87fa ,0x0a}, + {0x87fb ,0xc6}, + {0x87fc ,0xe5}, + {0x87fd ,0x43}, + {0x87fe ,0xfb}, + {0x87ff ,0xfd}, + {0x8800 ,0x7c}, + {0x8801 ,0x00}, + {0x8802 ,0x12}, + {0x8803 ,0x05}, + {0x8804 ,0x34}, + {0x8805 ,0x78}, + {0x8806 ,0x5c}, + {0x8807 ,0xa6}, + {0x8808 ,0x06}, + {0x8809 ,0x08}, + {0x880a ,0xa6}, + {0x880b ,0x07}, + {0x880c ,0xaf}, + {0x880d ,0x46}, + {0x880e ,0x7e}, + {0x880f ,0x00}, + {0x8810 ,0x78}, + {0x8811 ,0x54}, + {0x8812 ,0x12}, + {0x8813 ,0x0a}, + {0x8814 ,0xc8}, + {0x8815 ,0xad}, + {0x8816 ,0x03}, + {0x8817 ,0x7c}, + {0x8818 ,0x00}, + {0x8819 ,0x12}, + {0x881a ,0x05}, + {0x881b ,0x34}, + {0x881c ,0x78}, + {0x881d ,0x58}, + {0x881e ,0xa6}, + {0x881f ,0x06}, + {0x8820 ,0x08}, + {0x8821 ,0xa6}, + {0x8822 ,0x07}, + {0x8823 ,0xc3}, + {0x8824 ,0x78}, + {0x8825 ,0x5b}, + {0x8826 ,0xe6}, + {0x8827 ,0x94}, + {0x8828 ,0x08}, + {0x8829 ,0x18}, + {0x882a ,0xe6}, + {0x882b ,0x94}, + {0x882c ,0x00}, + {0x882d ,0x50}, + {0x882e ,0x05}, + {0x882f ,0x76}, + {0x8830 ,0x00}, + {0x8831 ,0x08}, + {0x8832 ,0x76}, + {0x8833 ,0x08}, + {0x8834 ,0xc3}, + {0x8835 ,0x78}, + {0x8836 ,0x5d}, + {0x8837 ,0xe6}, + {0x8838 ,0x94}, + {0x8839 ,0x08}, + {0x883a ,0x18}, + {0x883b ,0xe6}, + {0x883c ,0x94}, + {0x883d ,0x00}, + {0x883e ,0x50}, + {0x883f ,0x05}, + {0x8840 ,0x76}, + {0x8841 ,0x00}, + {0x8842 ,0x08}, + {0x8843 ,0x76}, + {0x8844 ,0x08}, + {0x8845 ,0x78}, + {0x8846 ,0x5a}, + {0x8847 ,0x12}, + {0x8848 ,0x0a}, + {0x8849 ,0xd8}, + {0x884a ,0xff}, + {0x884b ,0xd3}, + {0x884c ,0x78}, + {0x884d ,0x57}, + {0x884e ,0xe6}, + {0x884f ,0x9f}, + {0x8850 ,0x18}, + {0x8851 ,0xe6}, + {0x8852 ,0x9e}, + {0x8853 ,0x40}, + {0x8854 ,0x0e}, + {0x8855 ,0x78}, + {0x8856 ,0x5a}, + {0x8857 ,0xe6}, + {0x8858 ,0x13}, + {0x8859 ,0xfe}, + {0x885a ,0x08}, + {0x885b ,0xe6}, + {0x885c ,0x78}, + {0x885d ,0x57}, + {0x885e ,0x12}, + {0x885f ,0x0b}, + {0x8860 ,0x1a}, + {0x8861 ,0x80}, + {0x8862 ,0x04}, + {0x8863 ,0x7e}, + {0x8864 ,0x00}, + {0x8865 ,0x7f}, + {0x8866 ,0x00}, + {0x8867 ,0x78}, + {0x8868 ,0x5e}, + {0x8869 ,0x12}, + {0x886a ,0x0a}, + {0x886b ,0xd0}, + {0x886c ,0xff}, + {0x886d ,0xd3}, + {0x886e ,0x78}, + {0x886f ,0x59}, + {0x8870 ,0xe6}, + {0x8871 ,0x9f}, + {0x8872 ,0x18}, + {0x8873 ,0xe6}, + {0x8874 ,0x9e}, + {0x8875 ,0x40}, + {0x8876 ,0x0e}, + {0x8877 ,0x78}, + {0x8878 ,0x5c}, + {0x8879 ,0xe6}, + {0x887a ,0x13}, + {0x887b ,0xfe}, + {0x887c ,0x08}, + {0x887d ,0xe6}, + {0x887e ,0x78}, + {0x887f ,0x59}, + {0x8880 ,0x12}, + {0x8881 ,0x0b}, + {0x8882 ,0x1a}, + {0x8883 ,0x80}, + {0x8884 ,0x04}, + {0x8885 ,0x7e}, + {0x8886 ,0x00}, + {0x8887 ,0x7f}, + {0x8888 ,0x00}, + {0x8889 ,0xe4}, + {0x888a ,0xfc}, + {0x888b ,0xfd}, + {0x888c ,0x78}, + {0x888d ,0x62}, + {0x888e ,0x12}, + {0x888f ,0x06}, + {0x8890 ,0xfa}, + {0x8891 ,0x78}, + {0x8892 ,0x5a}, + {0x8893 ,0x12}, + {0x8894 ,0x0a}, + {0x8895 ,0xd8}, + {0x8896 ,0x78}, + {0x8897 ,0x57}, + {0x8898 ,0x26}, + {0x8899 ,0xff}, + {0x889a ,0xee}, + {0x889b ,0x18}, + {0x889c ,0x36}, + {0x889d ,0xfe}, + {0x889e ,0x78}, + {0x889f ,0x66}, + {0x88a0 ,0x12}, + {0x88a1 ,0x0a}, + {0x88a2 ,0xd0}, + {0x88a3 ,0x78}, + {0x88a4 ,0x59}, + {0x88a5 ,0x26}, + {0x88a6 ,0xff}, + {0x88a7 ,0xee}, + {0x88a8 ,0x18}, + {0x88a9 ,0x36}, + {0x88aa ,0xfe}, + {0x88ab ,0xe4}, + {0x88ac ,0xfc}, + {0x88ad ,0xfd}, + {0x88ae ,0x78}, + {0x88af ,0x6a}, + {0x88b0 ,0x12}, + {0x88b1 ,0x06}, + {0x88b2 ,0xfa}, + {0x88b3 ,0x12}, + {0x88b4 ,0x0a}, + {0x88b5 ,0xe0}, + {0x88b6 ,0x78}, + {0x88b7 ,0x66}, + {0x88b8 ,0x12}, + {0x88b9 ,0x06}, + {0x88ba ,0xed}, + {0x88bb ,0xd3}, + {0x88bc ,0x12}, + {0x88bd ,0x06}, + {0x88be ,0xa6}, + {0x88bf ,0x40}, + {0x88c0 ,0x08}, + {0x88c1 ,0x12}, + {0x88c2 ,0x0a}, + {0x88c3 ,0xe0}, + {0x88c4 ,0x78}, + {0x88c5 ,0x66}, + {0x88c6 ,0x12}, + {0x88c7 ,0x06}, + {0x88c8 ,0xfa}, + {0x88c9 ,0x78}, + {0x88ca ,0x54}, + {0x88cb ,0x12}, + {0x88cc ,0x0a}, + {0x88cd ,0xe2}, + {0x88ce ,0x78}, + {0x88cf ,0x6a}, + {0x88d0 ,0x12}, + {0x88d1 ,0x06}, + {0x88d2 ,0xed}, + {0x88d3 ,0xd3}, + {0x88d4 ,0x12}, + {0x88d5 ,0x06}, + {0x88d6 ,0xa6}, + {0x88d7 ,0x40}, + {0x88d8 ,0x0a}, + {0x88d9 ,0x78}, + {0x88da ,0x54}, + {0x88db ,0x12}, + {0x88dc ,0x0a}, + {0x88dd ,0xe2}, + {0x88de ,0x78}, + {0x88df ,0x6a}, + {0x88e0 ,0x12}, + {0x88e1 ,0x06}, + {0x88e2 ,0xfa}, + {0x88e3 ,0x78}, + {0x88e4 ,0x61}, + {0x88e5 ,0xe6}, + {0x88e6 ,0x90}, + {0x88e7 ,0x60}, + {0x88e8 ,0x01}, + {0x88e9 ,0xf0}, + {0x88ea ,0x78}, + {0x88eb ,0x65}, + {0x88ec ,0xe6}, + {0x88ed ,0xa3}, + {0x88ee ,0xf0}, + {0x88ef ,0x78}, + {0x88f0 ,0x69}, + {0x88f1 ,0xe6}, + {0x88f2 ,0xa3}, + {0x88f3 ,0xf0}, + {0x88f4 ,0x78}, + {0x88f5 ,0x55}, + {0x88f6 ,0xe6}, + {0x88f7 ,0xa3}, + {0x88f8 ,0xf0}, + {0x88f9 ,0x7d}, + {0x88fa ,0x01}, + {0x88fb ,0x78}, + {0x88fc ,0x61}, + {0x88fd ,0x12}, + {0x88fe ,0x0a}, + {0x88ff ,0xfb}, + {0x8900 ,0x24}, + {0x8901 ,0x01}, + {0x8902 ,0x12}, + {0x8903 ,0x0a}, + {0x8904 ,0xb8}, + {0x8905 ,0x78}, + {0x8906 ,0x65}, + {0x8907 ,0x12}, + {0x8908 ,0x0a}, + {0x8909 ,0xfb}, + {0x890a ,0x24}, + {0x890b ,0x02}, + {0x890c ,0x12}, + {0x890d ,0x0a}, + {0x890e ,0xb8}, + {0x890f ,0x78}, + {0x8910 ,0x69}, + {0x8911 ,0x12}, + {0x8912 ,0x0a}, + {0x8913 ,0xfb}, + {0x8914 ,0x24}, + {0x8915 ,0x03}, + {0x8916 ,0x12}, + {0x8917 ,0x0a}, + {0x8918 ,0xb8}, + {0x8919 ,0x78}, + {0x891a ,0x6d}, + {0x891b ,0x12}, + {0x891c ,0x0a}, + {0x891d ,0xfb}, + {0x891e ,0x24}, + {0x891f ,0x04}, + {0x8920 ,0x12}, + {0x8921 ,0x0a}, + {0x8922 ,0xb8}, + {0x8923 ,0x0d}, + {0x8924 ,0xbd}, + {0x8925 ,0x05}, + {0x8926 ,0xd4}, + {0x8927 ,0x22}, + {0x8928 ,0xc0}, + {0x8929 ,0xe0}, + {0x892a ,0xc0}, + {0x892b ,0x83}, + {0x892c ,0xc0}, + {0x892d ,0x82}, + {0x892e ,0xc0}, + {0x892f ,0xd0}, + {0x8930 ,0x90}, + {0x8931 ,0x3f}, + {0x8932 ,0x0c}, + {0x8933 ,0xe0}, + {0x8934 ,0xf5}, + {0x8935 ,0x32}, + {0x8936 ,0xe5}, + {0x8937 ,0x32}, + {0x8938 ,0x30}, + {0x8939 ,0xe3}, + {0x893a ,0x74}, + {0x893b ,0x30}, + {0x893c ,0x36}, + {0x893d ,0x66}, + {0x893e ,0x90}, + {0x893f ,0x60}, + {0x8940 ,0x19}, + {0x8941 ,0xe0}, + {0x8942 ,0xf5}, + {0x8943 ,0x0a}, + {0x8944 ,0xa3}, + {0x8945 ,0xe0}, + {0x8946 ,0xf5}, + {0x8947 ,0x0b}, + {0x8948 ,0x90}, + {0x8949 ,0x60}, + {0x894a ,0x1d}, + {0x894b ,0xe0}, + {0x894c ,0xf5}, + {0x894d ,0x14}, + {0x894e ,0xa3}, + {0x894f ,0xe0}, + {0x8950 ,0xf5}, + {0x8951 ,0x15}, + {0x8952 ,0x90}, + {0x8953 ,0x60}, + {0x8954 ,0x21}, + {0x8955 ,0xe0}, + {0x8956 ,0xf5}, + {0x8957 ,0x0c}, + {0x8958 ,0xa3}, + {0x8959 ,0xe0}, + {0x895a ,0xf5}, + {0x895b ,0x0d}, + {0x895c ,0x90}, + {0x895d ,0x60}, + {0x895e ,0x29}, + {0x895f ,0xe0}, + {0x8960 ,0xf5}, + {0x8961 ,0x0e}, + {0x8962 ,0xa3}, + {0x8963 ,0xe0}, + {0x8964 ,0xf5}, + {0x8965 ,0x0f}, + {0x8966 ,0x90}, + {0x8967 ,0x60}, + {0x8968 ,0x31}, + {0x8969 ,0xe0}, + {0x896a ,0xf5}, + {0x896b ,0x10}, + {0x896c ,0xa3}, + {0x896d ,0xe0}, + {0x896e ,0xf5}, + {0x896f ,0x11}, + {0x8970 ,0x90}, + {0x8971 ,0x60}, + {0x8972 ,0x39}, + {0x8973 ,0xe0}, + {0x8974 ,0xf5}, + {0x8975 ,0x12}, + {0x8976 ,0xa3}, + {0x8977 ,0xe0}, + {0x8978 ,0xf5}, + {0x8979 ,0x13}, + {0x897a ,0x30}, + {0x897b ,0x01}, + {0x897c ,0x06}, + {0x897d ,0x30}, + {0x897e ,0x33}, + {0x897f ,0x03}, + {0x8980 ,0xd3}, + {0x8981 ,0x80}, + {0x8982 ,0x01}, + {0x8983 ,0xc3}, + {0x8984 ,0x92}, + {0x8985 ,0x09}, + {0x8986 ,0x30}, + {0x8987 ,0x02}, + {0x8988 ,0x06}, + {0x8989 ,0x30}, + {0x898a ,0x33}, + {0x898b ,0x03}, + {0x898c ,0xd3}, + {0x898d ,0x80}, + {0x898e ,0x01}, + {0x898f ,0xc3}, + {0x8990 ,0x92}, + {0x8991 ,0x0a}, + {0x8992 ,0x30}, + {0x8993 ,0x33}, + {0x8994 ,0x0c}, + {0x8995 ,0x30}, + {0x8996 ,0x03}, + {0x8997 ,0x09}, + {0x8998 ,0x20}, + {0x8999 ,0x02}, + {0x899a ,0x06}, + {0x899b ,0x20}, + {0x899c ,0x01}, + {0x899d ,0x03}, + {0x899e ,0xd3}, + {0x899f ,0x80}, + {0x89a0 ,0x01}, + {0x89a1 ,0xc3}, + {0x89a2 ,0x92}, + {0x89a3 ,0x0b}, + {0x89a4 ,0x90}, + {0x89a5 ,0x30}, + {0x89a6 ,0x01}, + {0x89a7 ,0xe0}, + {0x89a8 ,0x44}, + {0x89a9 ,0x40}, + {0x89aa ,0xf0}, + {0x89ab ,0xe0}, + {0x89ac ,0x54}, + {0x89ad ,0xbf}, + {0x89ae ,0xf0}, + {0x89af ,0xe5}, + {0x89b0 ,0x32}, + {0x89b1 ,0x30}, + {0x89b2 ,0xe1}, + {0x89b3 ,0x14}, + {0x89b4 ,0x30}, + {0x89b5 ,0x34}, + {0x89b6 ,0x11}, + {0x89b7 ,0x90}, + {0x89b8 ,0x30}, + {0x89b9 ,0x22}, + {0x89ba ,0xe0}, + {0x89bb ,0xf5}, + {0x89bc ,0x08}, + {0x89bd ,0xe4}, + {0x89be ,0xf0}, + {0x89bf ,0x30}, + {0x89c0 ,0x00}, + {0x89c1 ,0x03}, + {0x89c2 ,0xd3}, + {0x89c3 ,0x80}, + {0x89c4 ,0x01}, + {0x89c5 ,0xc3}, + {0x89c6 ,0x92}, + {0x89c7 ,0x08}, + {0x89c8 ,0xe5}, + {0x89c9 ,0x32}, + {0x89ca ,0x30}, + {0x89cb ,0xe5}, + {0x89cc ,0x12}, + {0x89cd ,0x90}, + {0x89ce ,0x56}, + {0x89cf ,0xa1}, + {0x89d0 ,0xe0}, + {0x89d1 ,0xf5}, + {0x89d2 ,0x09}, + {0x89d3 ,0x30}, + {0x89d4 ,0x31}, + {0x89d5 ,0x09}, + {0x89d6 ,0x30}, + {0x89d7 ,0x05}, + {0x89d8 ,0x03}, + {0x89d9 ,0xd3}, + {0x89da ,0x80}, + {0x89db ,0x01}, + {0x89dc ,0xc3}, + {0x89dd ,0x92}, + {0x89de ,0x0d}, + {0x89df ,0x90}, + {0x89e0 ,0x3f}, + {0x89e1 ,0x0c}, + {0x89e2 ,0xe5}, + {0x89e3 ,0x32}, + {0x89e4 ,0xf0}, + {0x89e5 ,0xd0}, + {0x89e6 ,0xd0}, + {0x89e7 ,0xd0}, + {0x89e8 ,0x82}, + {0x89e9 ,0xd0}, + {0x89ea ,0x83}, + {0x89eb ,0xd0}, + {0x89ec ,0xe0}, + {0x89ed ,0x32}, + {0x89ee ,0x85}, + {0x89ef ,0x08}, + {0x89f0 ,0x41}, + {0x89f1 ,0x90}, + {0x89f2 ,0x30}, + {0x89f3 ,0x24}, + {0x89f4 ,0xe0}, + {0x89f5 ,0xf5}, + {0x89f6 ,0x3d}, + {0x89f7 ,0xa3}, + {0x89f8 ,0xe0}, + {0x89f9 ,0xf5}, + {0x89fa ,0x3e}, + {0x89fb ,0xa3}, + {0x89fc ,0xe0}, + {0x89fd ,0xf5}, + {0x89fe ,0x3f}, + {0x89ff ,0xa3}, + {0x8a00 ,0xe0}, + {0x8a01 ,0xf5}, + {0x8a02 ,0x40}, + {0x8a03 ,0xa3}, + {0x8a04 ,0xe0}, + {0x8a05 ,0xf5}, + {0x8a06 ,0x3c}, + {0x8a07 ,0xd2}, + {0x8a08 ,0x34}, + {0x8a09 ,0xe5}, + {0x8a0a ,0x41}, + {0x8a0b ,0x12}, + {0x8a0c ,0x07}, + {0x8a0d ,0x12}, + {0x8a0e ,0x0a}, + {0x8a0f ,0x33}, + {0x8a10 ,0x03}, + {0x8a11 ,0x0a}, + {0x8a12 ,0x40}, + {0x8a13 ,0x04}, + {0x8a14 ,0x0a}, + {0x8a15 ,0x51}, + {0x8a16 ,0x05}, + {0x8a17 ,0x0a}, + {0x8a18 ,0x54}, + {0x8a19 ,0x06}, + {0x8a1a ,0x0a}, + {0x8a1b ,0x5d}, + {0x8a1c ,0x08}, + {0x8a1d ,0x0a}, + {0x8a1e ,0x6d}, + {0x8a1f ,0x12}, + {0x8a20 ,0x0a}, + {0x8a21 ,0x72}, + {0x8a22 ,0x1a}, + {0x8a23 ,0x0a}, + {0x8a24 ,0x7d}, + {0x8a25 ,0x1b}, + {0x8a26 ,0x0a}, + {0x8a27 ,0x6d}, + {0x8a28 ,0x80}, + {0x8a29 ,0x0a}, + {0x8a2a ,0x6d}, + {0x8a2b ,0x81}, + {0x8a2c ,0x0a}, + {0x8a2d ,0x85}, + {0x8a2e ,0xec}, + {0x8a2f ,0x00}, + {0x8a30 ,0x00}, + {0x8a31 ,0x0a}, + {0x8a32 ,0xa3}, + {0x8a33 ,0x12}, + {0x8a34 ,0x0f}, + {0x8a35 ,0xd2}, + {0x8a36 ,0xd2}, + {0x8a37 ,0x36}, + {0x8a38 ,0xd2}, + {0x8a39 ,0x01}, + {0x8a3a ,0xc2}, + {0x8a3b ,0x02}, + {0x8a3c ,0x12}, + {0x8a3d ,0x0f}, + {0x8a3e ,0xd7}, + {0x8a3f ,0x22}, + {0x8a40 ,0xd2}, + {0x8a41 ,0x33}, + {0x8a42 ,0xd2}, + {0x8a43 ,0x36}, + {0x8a44 ,0xe5}, + {0x8a45 ,0x3d}, + {0x8a46 ,0xd3}, + {0x8a47 ,0x94}, + {0x8a48 ,0x00}, + {0x8a49 ,0x40}, + {0x8a4a ,0x03}, + {0x8a4b ,0x12}, + {0x8a4c ,0x0f}, + {0x8a4d ,0xd2}, + {0x8a4e ,0xd2}, + {0x8a4f ,0x03}, + {0x8a50 ,0x22}, + {0x8a51 ,0xd2}, + {0x8a52 ,0x03}, + {0x8a53 ,0x22}, + {0x8a54 ,0xc2}, + {0x8a55 ,0x03}, + {0x8a56 ,0x20}, + {0x8a57 ,0x01}, + {0x8a58 ,0x4a}, + {0x8a59 ,0x30}, + {0x8a5a ,0x02}, + {0x8a5b ,0x2c}, + {0x8a5c ,0x22}, + {0x8a5d ,0xc2}, + {0x8a5e ,0x01}, + {0x8a5f ,0xc2}, + {0x8a60 ,0x02}, + {0x8a61 ,0xc2}, + {0x8a62 ,0x03}, + {0x8a63 ,0x12}, + {0x8a64 ,0x0d}, + {0x8a65 ,0x39}, + {0x8a66 ,0x75}, + {0x8a67 ,0x1e}, + {0x8a68 ,0x70}, + {0x8a69 ,0xd2}, + {0x8a6a ,0x35}, + {0x8a6b ,0x80}, + {0x8a6c ,0x1b}, + {0x8a6d ,0x12}, + {0x8a6e ,0x0b}, + {0x8a6f ,0xcc}, + {0x8a70 ,0x80}, + {0x8a71 ,0x16}, + {0x8a72 ,0x85}, + {0x8a73 ,0x40}, + {0x8a74 ,0x4a}, + {0x8a75 ,0x85}, + {0x8a76 ,0x3c}, + {0x8a77 ,0x4b}, + {0x8a78 ,0x12}, + {0x8a79 ,0x0b}, + {0x8a7a ,0x39}, + {0x8a7b ,0x80}, + {0x8a7c ,0x0b}, + {0x8a7d ,0x85}, + {0x8a7e ,0x4a}, + {0x8a7f ,0x40}, + {0x8a80 ,0x85}, + {0x8a81 ,0x4b}, + {0x8a82 ,0x3c}, + {0x8a83 ,0x80}, + {0x8a84 ,0x03}, + {0x8a85 ,0x12}, + {0x8a86 ,0x0f}, + {0x8a87 ,0x00}, + {0x8a88 ,0x90}, + {0x8a89 ,0x30}, + {0x8a8a ,0x24}, + {0x8a8b ,0xe5}, + {0x8a8c ,0x3d}, + {0x8a8d ,0xf0}, + {0x8a8e ,0xa3}, + {0x8a8f ,0xe5}, + {0x8a90 ,0x3e}, + {0x8a91 ,0xf0}, + {0x8a92 ,0xa3}, + {0x8a93 ,0xe5}, + {0x8a94 ,0x3f}, + {0x8a95 ,0xf0}, + {0x8a96 ,0xa3}, + {0x8a97 ,0xe5}, + {0x8a98 ,0x40}, + {0x8a99 ,0xf0}, + {0x8a9a ,0xa3}, + {0x8a9b ,0xe5}, + {0x8a9c ,0x3c}, + {0x8a9d ,0xf0}, + {0x8a9e ,0x90}, + {0x8a9f ,0x30}, + {0x8aa0 ,0x23}, + {0x8aa1 ,0xe4}, + {0x8aa2 ,0xf0}, + {0x8aa3 ,0x22}, + {0x8aa4 ,0xe0}, + {0x8aa5 ,0xa3}, + {0x8aa6 ,0xe0}, + {0x8aa7 ,0x75}, + {0x8aa8 ,0xf0}, + {0x8aa9 ,0x02}, + {0x8aaa ,0xa4}, + {0x8aab ,0xff}, + {0x8aac ,0xae}, + {0x8aad ,0xf0}, + {0x8aae ,0xc3}, + {0x8aaf ,0x08}, + {0x8ab0 ,0xe6}, + {0x8ab1 ,0x9f}, + {0x8ab2 ,0xf6}, + {0x8ab3 ,0x18}, + {0x8ab4 ,0xe6}, + {0x8ab5 ,0x9e}, + {0x8ab6 ,0xf6}, + {0x8ab7 ,0x22}, + {0x8ab8 ,0xff}, + {0x8ab9 ,0xe5}, + {0x8aba ,0xf0}, + {0x8abb ,0x34}, + {0x8abc ,0x60}, + {0x8abd ,0x8f}, + {0x8abe ,0x82}, + {0x8abf ,0xf5}, + {0x8ac0 ,0x83}, + {0x8ac1 ,0xec}, + {0x8ac2 ,0xf0}, + {0x8ac3 ,0x22}, + {0x8ac4 ,0x78}, + {0x8ac5 ,0x52}, + {0x8ac6 ,0x7e}, + {0x8ac7 ,0x00}, + {0x8ac8 ,0xe6}, + {0x8ac9 ,0xfc}, + {0x8aca ,0x08}, + {0x8acb ,0xe6}, + {0x8acc ,0xfd}, + {0x8acd ,0x02}, + {0x8ace ,0x05}, + {0x8acf ,0x22}, + {0x8ad0 ,0xe4}, + {0x8ad1 ,0xfc}, + {0x8ad2 ,0xfd}, + {0x8ad3 ,0x12}, + {0x8ad4 ,0x06}, + {0x8ad5 ,0xfa}, + {0x8ad6 ,0x78}, + {0x8ad7 ,0x5c}, + {0x8ad8 ,0xe6}, + {0x8ad9 ,0xc3}, + {0x8ada ,0x13}, + {0x8adb ,0xfe}, + {0x8adc ,0x08}, + {0x8add ,0xe6}, + {0x8ade ,0x13}, + {0x8adf ,0x22}, + {0x8ae0 ,0x78}, + {0x8ae1 ,0x52}, + {0x8ae2 ,0xe6}, + {0x8ae3 ,0xfe}, + {0x8ae4 ,0x08}, + {0x8ae5 ,0xe6}, + {0x8ae6 ,0xff}, + {0x8ae7 ,0xe4}, + {0x8ae8 ,0xfc}, + {0x8ae9 ,0xfd}, + {0x8aea ,0x22}, + {0x8aeb ,0xe7}, + {0x8aec ,0xc4}, + {0x8aed ,0xf8}, + {0x8aee ,0x54}, + {0x8aef ,0xf0}, + {0x8af0 ,0xc8}, + {0x8af1 ,0x68}, + {0x8af2 ,0xf7}, + {0x8af3 ,0x09}, + {0x8af4 ,0xe7}, + {0x8af5 ,0xc4}, + {0x8af6 ,0x54}, + {0x8af7 ,0x0f}, + {0x8af8 ,0x48}, + {0x8af9 ,0xf7}, + {0x8afa ,0x22}, + {0x8afb ,0xe6}, + {0x8afc ,0xfc}, + {0x8afd ,0xed}, + {0x8afe ,0x75}, + {0x8aff ,0xf0}, + {0x8b00 ,0x04}, + {0x8b01 ,0xa4}, + {0x8b02 ,0x22}, + {0x8b03 ,0x12}, + {0x8b04 ,0x06}, + {0x8b05 ,0xdd}, + {0x8b06 ,0x8f}, + {0x8b07 ,0x48}, + {0x8b08 ,0x8e}, + {0x8b09 ,0x47}, + {0x8b0a ,0x8d}, + {0x8b0b ,0x46}, + {0x8b0c ,0x8c}, + {0x8b0d ,0x45}, + {0x8b0e ,0x22}, + {0x8b0f ,0xe0}, + {0x8b10 ,0xfe}, + {0x8b11 ,0xa3}, + {0x8b12 ,0xe0}, + {0x8b13 ,0xfd}, + {0x8b14 ,0xee}, + {0x8b15 ,0xf6}, + {0x8b16 ,0xed}, + {0x8b17 ,0x08}, + {0x8b18 ,0xf6}, + {0x8b19 ,0x22}, + {0x8b1a ,0x13}, + {0x8b1b ,0xff}, + {0x8b1c ,0xc3}, + {0x8b1d ,0xe6}, + {0x8b1e ,0x9f}, + {0x8b1f ,0xff}, + {0x8b20 ,0x18}, + {0x8b21 ,0xe6}, + {0x8b22 ,0x9e}, + {0x8b23 ,0xfe}, + {0x8b24 ,0x22}, + {0x8b25 ,0xfb}, + {0x8b26 ,0xd3}, + {0x8b27 ,0xed}, + {0x8b28 ,0x9b}, + {0x8b29 ,0x74}, + {0x8b2a ,0x80}, + {0x8b2b ,0xf8}, + {0x8b2c ,0x6c}, + {0x8b2d ,0x98}, + {0x8b2e ,0x22}, + {0x8b2f ,0xe6}, + {0x8b30 ,0xc3}, + {0x8b31 ,0x13}, + {0x8b32 ,0xf7}, + {0x8b33 ,0x08}, + {0x8b34 ,0xe6}, + {0x8b35 ,0x13}, + {0x8b36 ,0x09}, + {0x8b37 ,0xf7}, + {0x8b38 ,0x22}, + {0x8b39 ,0x90}, + {0x8b3a ,0x0e}, + {0x8b3b ,0x7e}, + {0x8b3c ,0xe4}, + {0x8b3d ,0x93}, + {0x8b3e ,0xfe}, + {0x8b3f ,0x74}, + {0x8b40 ,0x01}, + {0x8b41 ,0x93}, + {0x8b42 ,0xff}, + {0x8b43 ,0xc3}, + {0x8b44 ,0x90}, + {0x8b45 ,0x0e}, + {0x8b46 ,0x7c}, + {0x8b47 ,0x74}, + {0x8b48 ,0x01}, + {0x8b49 ,0x93}, + {0x8b4a ,0x9f}, + {0x8b4b ,0xff}, + {0x8b4c ,0xe4}, + {0x8b4d ,0x93}, + {0x8b4e ,0x9e}, + {0x8b4f ,0xfe}, + {0x8b50 ,0xe4}, + {0x8b51 ,0x8f}, + {0x8b52 ,0x3b}, + {0x8b53 ,0x8e}, + {0x8b54 ,0x3a}, + {0x8b55 ,0xf5}, + {0x8b56 ,0x39}, + {0x8b57 ,0xf5}, + {0x8b58 ,0x38}, + {0x8b59 ,0xab}, + {0x8b5a ,0x3b}, + {0x8b5b ,0xaa}, + {0x8b5c ,0x3a}, + {0x8b5d ,0xa9}, + {0x8b5e ,0x39}, + {0x8b5f ,0xa8}, + {0x8b60 ,0x38}, + {0x8b61 ,0xaf}, + {0x8b62 ,0x4b}, + {0x8b63 ,0xfc}, + {0x8b64 ,0xfd}, + {0x8b65 ,0xfe}, + {0x8b66 ,0x12}, + {0x8b67 ,0x05}, + {0x8b68 ,0x89}, + {0x8b69 ,0x12}, + {0x8b6a ,0x0f}, + {0x8b6b ,0x91}, + {0x8b6c ,0xe4}, + {0x8b6d ,0x7b}, + {0x8b6e ,0xff}, + {0x8b6f ,0xfa}, + {0x8b70 ,0xf9}, + {0x8b71 ,0xf8}, + {0x8b72 ,0x12}, + {0x8b73 ,0x06}, + {0x8b74 ,0x14}, + {0x8b75 ,0x12}, + {0x8b76 ,0x0f}, + {0x8b77 ,0x91}, + {0x8b78 ,0x90}, + {0x8b79 ,0x0e}, + {0x8b7a ,0x69}, + {0x8b7b ,0xe4}, + {0x8b7c ,0x12}, + {0x8b7d ,0x0f}, + {0x8b7e ,0xa6}, + {0x8b7f ,0x12}, + {0x8b80 ,0x0f}, + {0x8b81 ,0x91}, + {0x8b82 ,0xe4}, + {0x8b83 ,0x85}, + {0x8b84 ,0x4a}, + {0x8b85 ,0x37}, + {0x8b86 ,0xf5}, + {0x8b87 ,0x36}, + {0x8b88 ,0xf5}, + {0x8b89 ,0x35}, + {0x8b8a ,0xf5}, + {0x8b8b ,0x34}, + {0x8b8c ,0xaf}, + {0x8b8d ,0x37}, + {0x8b8e ,0xae}, + {0x8b8f ,0x36}, + {0x8b90 ,0xad}, + {0x8b91 ,0x35}, + {0x8b92 ,0xac}, + {0x8b93 ,0x34}, + {0x8b94 ,0xa3}, + {0x8b95 ,0x12}, + {0x8b96 ,0x0f}, + {0x8b97 ,0xa6}, + {0x8b98 ,0x8f}, + {0x8b99 ,0x37}, + {0x8b9a ,0x8e}, + {0x8b9b ,0x36}, + {0x8b9c ,0x8d}, + {0x8b9d ,0x35}, + {0x8b9e ,0x8c}, + {0x8b9f ,0x34}, + {0x8ba0 ,0xe5}, + {0x8ba1 ,0x3b}, + {0x8ba2 ,0x45}, + {0x8ba3 ,0x37}, + {0x8ba4 ,0xf5}, + {0x8ba5 ,0x3b}, + {0x8ba6 ,0xe5}, + {0x8ba7 ,0x3a}, + {0x8ba8 ,0x45}, + {0x8ba9 ,0x36}, + {0x8baa ,0xf5}, + {0x8bab ,0x3a}, + {0x8bac ,0xe5}, + {0x8bad ,0x39}, + {0x8bae ,0x45}, + {0x8baf ,0x35}, + {0x8bb0 ,0xf5}, + {0x8bb1 ,0x39}, + {0x8bb2 ,0xe5}, + {0x8bb3 ,0x38}, + {0x8bb4 ,0x45}, + {0x8bb5 ,0x34}, + {0x8bb6 ,0xf5}, + {0x8bb7 ,0x38}, + {0x8bb8 ,0xe4}, + {0x8bb9 ,0xf5}, + {0x8bba ,0x22}, + {0x8bbb ,0xf5}, + {0x8bbc ,0x23}, + {0x8bbd ,0x85}, + {0x8bbe ,0x3b}, + {0x8bbf ,0x31}, + {0x8bc0 ,0x85}, + {0x8bc1 ,0x3a}, + {0x8bc2 ,0x30}, + {0x8bc3 ,0x85}, + {0x8bc4 ,0x39}, + {0x8bc5 ,0x2f}, + {0x8bc6 ,0x85}, + {0x8bc7 ,0x38}, + {0x8bc8 ,0x2e}, + {0x8bc9 ,0x02}, + {0x8bca ,0x0f}, + {0x8bcb ,0x63}, + {0x8bcc ,0xe5}, + {0x8bcd ,0x3c}, + {0x8bce ,0xd3}, + {0x8bcf ,0x94}, + {0x8bd0 ,0x01}, + {0x8bd1 ,0x40}, + {0x8bd2 ,0x0b}, + {0x8bd3 ,0x90}, + {0x8bd4 ,0x0e}, + {0x8bd5 ,0x88}, + {0x8bd6 ,0x12}, + {0x8bd7 ,0x0b}, + {0x8bd8 ,0x03}, + {0x8bd9 ,0x90}, + {0x8bda ,0x0e}, + {0x8bdb ,0x86}, + {0x8bdc ,0x80}, + {0x8bdd ,0x09}, + {0x8bde ,0x90}, + {0x8bdf ,0x0e}, + {0x8be0 ,0x82}, + {0x8be1 ,0x12}, + {0x8be2 ,0x0b}, + {0x8be3 ,0x03}, + {0x8be4 ,0x90}, + {0x8be5 ,0x0e}, + {0x8be6 ,0x80}, + {0x8be7 ,0xe4}, + {0x8be8 ,0x93}, + {0x8be9 ,0xf5}, + {0x8bea ,0x44}, + {0x8beb ,0xa3}, + {0x8bec ,0xe4}, + {0x8bed ,0x93}, + {0x8bee ,0xf5}, + {0x8bef ,0x43}, + {0x8bf0 ,0xe5}, + {0x8bf1 ,0x3c}, + {0x8bf2 ,0xd3}, + {0x8bf3 ,0x94}, + {0x8bf4 ,0x00}, + {0x8bf5 ,0x40}, + {0x8bf6 ,0x06}, + {0x8bf7 ,0x85}, + {0x8bf8 ,0x3d}, + {0x8bf9 ,0x45}, + {0x8bfa ,0x85}, + {0x8bfb ,0x3e}, + {0x8bfc ,0x46}, + {0x8bfd ,0xe5}, + {0x8bfe ,0x47}, + {0x8bff ,0xc3}, + {0x8c00 ,0x13}, + {0x8c01 ,0xff}, + {0x8c02 ,0xe5}, + {0x8c03 ,0x45}, + {0x8c04 ,0xc3}, + {0x8c05 ,0x9f}, + {0x8c06 ,0x50}, + {0x8c07 ,0x02}, + {0x8c08 ,0x8f}, + {0x8c09 ,0x45}, + {0x8c0a ,0xe5}, + {0x8c0b ,0x48}, + {0x8c0c ,0xc3}, + {0x8c0d ,0x13}, + {0x8c0e ,0xff}, + {0x8c0f ,0xe5}, + {0x8c10 ,0x46}, + {0x8c11 ,0xc3}, + {0x8c12 ,0x9f}, + {0x8c13 ,0x50}, + {0x8c14 ,0x02}, + {0x8c15 ,0x8f}, + {0x8c16 ,0x46}, + {0x8c17 ,0xe5}, + {0x8c18 ,0x47}, + {0x8c19 ,0xc3}, + {0x8c1a ,0x13}, + {0x8c1b ,0xff}, + {0x8c1c ,0xfd}, + {0x8c1d ,0xe5}, + {0x8c1e ,0x45}, + {0x8c1f ,0x2d}, + {0x8c20 ,0xfd}, + {0x8c21 ,0xe4}, + {0x8c22 ,0x33}, + {0x8c23 ,0xfc}, + {0x8c24 ,0xe5}, + {0x8c25 ,0x44}, + {0x8c26 ,0x12}, + {0x8c27 ,0x0b}, + {0x8c28 ,0x25}, + {0x8c29 ,0x40}, + {0x8c2a ,0x05}, + {0x8c2b ,0xe5}, + {0x8c2c ,0x44}, + {0x8c2d ,0x9f}, + {0x8c2e ,0xf5}, + {0x8c2f ,0x45}, + {0x8c30 ,0xe5}, + {0x8c31 ,0x48}, + {0x8c32 ,0xc3}, + {0x8c33 ,0x13}, + {0x8c34 ,0xff}, + {0x8c35 ,0xfd}, + {0x8c36 ,0xe5}, + {0x8c37 ,0x46}, + {0x8c38 ,0x2d}, + {0x8c39 ,0xfd}, + {0x8c3a ,0xe4}, + {0x8c3b ,0x33}, + {0x8c3c ,0xfc}, + {0x8c3d ,0xe5}, + {0x8c3e ,0x43}, + {0x8c3f ,0x12}, + {0x8c40 ,0x0b}, + {0x8c41 ,0x25}, + {0x8c42 ,0x40}, + {0x8c43 ,0x05}, + {0x8c44 ,0xe5}, + {0x8c45 ,0x43}, + {0x8c46 ,0x9f}, + {0x8c47 ,0xf5}, + {0x8c48 ,0x46}, + {0x8c49 ,0x02}, + {0x8c4a ,0x07}, + {0x8c4b ,0x38}, + {0x8c4c ,0xad}, + {0x8c4d ,0x39}, + {0x8c4e ,0xac}, + {0x8c4f ,0x38}, + {0x8c50 ,0xfa}, + {0x8c51 ,0xf9}, + {0x8c52 ,0xf8}, + {0x8c53 ,0x12}, + {0x8c54 ,0x05}, + {0x8c55 ,0x89}, + {0x8c56 ,0x8f}, + {0x8c57 ,0x3b}, + {0x8c58 ,0x8e}, + {0x8c59 ,0x3a}, + {0x8c5a ,0x8d}, + {0x8c5b ,0x39}, + {0x8c5c ,0x8c}, + {0x8c5d ,0x38}, + {0x8c5e ,0xab}, + {0x8c5f ,0x37}, + {0x8c60 ,0xaa}, + {0x8c61 ,0x36}, + {0x8c62 ,0xa9}, + {0x8c63 ,0x35}, + {0x8c64 ,0xa8}, + {0x8c65 ,0x34}, + {0x8c66 ,0x22}, + {0x8c67 ,0x90}, + {0x8c68 ,0x0e}, + {0x8c69 ,0x8c}, + {0x8c6a ,0xe4}, + {0x8c6b ,0x93}, + {0x8c6c ,0x25}, + {0x8c6d ,0xe0}, + {0x8c6e ,0x24}, + {0x8c6f ,0x0a}, + {0x8c70 ,0xf8}, + {0x8c71 ,0xe6}, + {0x8c72 ,0xfe}, + {0x8c73 ,0x08}, + {0x8c74 ,0xe6}, + {0x8c75 ,0xff}, + {0x8c76 ,0x22}, + {0x8c77 ,0x93}, + {0x8c78 ,0xff}, + {0x8c79 ,0xe4}, + {0x8c7a ,0xfc}, + {0x8c7b ,0xfd}, + {0x8c7c ,0xfe}, + {0x8c7d ,0x12}, + {0x8c7e ,0x05}, + {0x8c7f ,0x89}, + {0x8c80 ,0x8f}, + {0x8c81 ,0x37}, + {0x8c82 ,0x8e}, + {0x8c83 ,0x36}, + {0x8c84 ,0x8d}, + {0x8c85 ,0x35}, + {0x8c86 ,0x8c}, + {0x8c87 ,0x34}, + {0x8c88 ,0x22}, + {0x8c89 ,0xe6}, + {0x8c8a ,0xfe}, + {0x8c8b ,0x08}, + {0x8c8c ,0xe6}, + {0x8c8d ,0xff}, + {0x8c8e ,0xe4}, + {0x8c8f ,0x8f}, + {0x8c90 ,0x37}, + {0x8c91 ,0x8e}, + {0x8c92 ,0x36}, + {0x8c93 ,0xf5}, + {0x8c94 ,0x35}, + {0x8c95 ,0xf5}, + {0x8c96 ,0x34}, + {0x8c97 ,0x22}, + {0x8c98 ,0xef}, + {0x8c99 ,0x25}, + {0x8c9a ,0xe0}, + {0x8c9b ,0x24}, + {0x8c9c ,0x4e}, + {0x8c9d ,0xf8}, + {0x8c9e ,0xe6}, + {0x8c9f ,0xfc}, + {0x8ca0 ,0x08}, + {0x8ca1 ,0xe6}, + {0x8ca2 ,0xfd}, + {0x8ca3 ,0x22}, + {0x8ca4 ,0xd3}, + {0x8ca5 ,0x79}, + {0x8ca6 ,0x81}, + {0x8ca7 ,0xe7}, + {0x8ca8 ,0x78}, + {0x8ca9 ,0x7f}, + {0x8caa ,0x96}, + {0x8cab ,0x19}, + {0x8cac ,0xe7}, + {0x8cad ,0x18}, + {0x8cae ,0x96}, + {0x8caf ,0x22}, + {0x8cb0 ,0x78}, + {0x8cb1 ,0x89}, + {0x8cb2 ,0xef}, + {0x8cb3 ,0x26}, + {0x8cb4 ,0xf6}, + {0x8cb5 ,0x18}, + {0x8cb6 ,0xe4}, + {0x8cb7 ,0x36}, + {0x8cb8 ,0xf6}, + {0x8cb9 ,0x22}, + {0x8cba ,0xe4}, + {0x8cbb ,0x8f}, + {0x8cbc ,0x3b}, + {0x8cbd ,0x8e}, + {0x8cbe ,0x3a}, + {0x8cbf ,0xf5}, + {0x8cc0 ,0x39}, + {0x8cc1 ,0xf5}, + {0x8cc2 ,0x38}, + {0x8cc3 ,0x22}, + {0x8cc4 ,0x75}, + {0x8cc5 ,0x89}, + {0x8cc6 ,0x03}, + {0x8cc7 ,0x75}, + {0x8cc8 ,0xa8}, + {0x8cc9 ,0x01}, + {0x8cca ,0x75}, + {0x8ccb ,0xb8}, + {0x8ccc ,0x04}, + {0x8ccd ,0x75}, + {0x8cce ,0x34}, + {0x8ccf ,0xff}, + {0x8cd0 ,0x75}, + {0x8cd1 ,0x35}, + {0x8cd2 ,0x0e}, + {0x8cd3 ,0x75}, + {0x8cd4 ,0x36}, + {0x8cd5 ,0x15}, + {0x8cd6 ,0x75}, + {0x8cd7 ,0x37}, + {0x8cd8 ,0x0d}, + {0x8cd9 ,0x12}, + {0x8cda ,0x0d}, + {0x8cdb ,0xaa}, + {0x8cdc ,0x12}, + {0x8cdd ,0x00}, + {0x8cde ,0x09}, + {0x8cdf ,0x12}, + {0x8ce0 ,0x0b}, + {0x8ce1 ,0xcc}, + {0x8ce2 ,0x12}, + {0x8ce3 ,0x00}, + {0x8ce4 ,0x06}, + {0x8ce5 ,0xd2}, + {0x8ce6 ,0x00}, + {0x8ce7 ,0xd2}, + {0x8ce8 ,0x34}, + {0x8ce9 ,0xd2}, + {0x8cea ,0xaf}, + {0x8ceb ,0x75}, + {0x8cec ,0x34}, + {0x8ced ,0xff}, + {0x8cee ,0x75}, + {0x8cef ,0x35}, + {0x8cf0 ,0x0e}, + {0x8cf1 ,0x75}, + {0x8cf2 ,0x36}, + {0x8cf3 ,0x49}, + {0x8cf4 ,0x75}, + {0x8cf5 ,0x37}, + {0x8cf6 ,0x03}, + {0x8cf7 ,0x12}, + {0x8cf8 ,0x0d}, + {0x8cf9 ,0xaa}, + {0x8cfa ,0x30}, + {0x8cfb ,0x08}, + {0x8cfc ,0x09}, + {0x8cfd ,0xc2}, + {0x8cfe ,0x34}, + {0x8cff ,0x12}, + {0x8d00 ,0x09}, + {0x8d01 ,0xee}, + {0x8d02 ,0xc2}, + {0x8d03 ,0x08}, + {0x8d04 ,0xd2}, + {0x8d05 ,0x34}, + {0x8d06 ,0x30}, + {0x8d07 ,0x0b}, + {0x8d08 ,0x09}, + {0x8d09 ,0xc2}, + {0x8d0a ,0x36}, + {0x8d0b ,0x12}, + {0x8d0c ,0x00}, + {0x8d0d ,0x0e}, + {0x8d0e ,0xc2}, + {0x8d0f ,0x0b}, + {0x8d10 ,0xd2}, + {0x8d11 ,0x36}, + {0x8d12 ,0x30}, + {0x8d13 ,0x09}, + {0x8d14 ,0x09}, + {0x8d15 ,0xc2}, + {0x8d16 ,0x36}, + {0x8d17 ,0x12}, + {0x8d18 ,0x02}, + {0x8d19 ,0xa7}, + {0x8d1a ,0xc2}, + {0x8d1b ,0x09}, + {0x8d1c ,0xd2}, + {0x8d1d ,0x36}, + {0x8d1e ,0x30}, + {0x8d1f ,0x0e}, + {0x8d20 ,0x03}, + {0x8d21 ,0x12}, + {0x8d22 ,0x07}, + {0x8d23 ,0x38}, + {0x8d24 ,0x30}, + {0x8d25 ,0x35}, + {0x8d26 ,0xd3}, + {0x8d27 ,0x90}, + {0x8d28 ,0x30}, + {0x8d29 ,0x29}, + {0x8d2a ,0xe5}, + {0x8d2b ,0x1e}, + {0x8d2c ,0xf0}, + {0x8d2d ,0xb4}, + {0x8d2e ,0x10}, + {0x8d2f ,0x05}, + {0x8d30 ,0x90}, + {0x8d31 ,0x30}, + {0x8d32 ,0x23}, + {0x8d33 ,0xe4}, + {0x8d34 ,0xf0}, + {0x8d35 ,0xc2}, + {0x8d36 ,0x35}, + {0x8d37 ,0x80}, + {0x8d38 ,0xc1}, + {0x8d39 ,0xe4}, + {0x8d3a ,0xf5}, + {0x8d3b ,0x4b}, + {0x8d3c ,0x90}, + {0x8d3d ,0x0e}, + {0x8d3e ,0x7a}, + {0x8d3f ,0x93}, + {0x8d40 ,0xff}, + {0x8d41 ,0xe4}, + {0x8d42 ,0x8f}, + {0x8d43 ,0x37}, + {0x8d44 ,0xf5}, + {0x8d45 ,0x36}, + {0x8d46 ,0xf5}, + {0x8d47 ,0x35}, + {0x8d48 ,0xf5}, + {0x8d49 ,0x34}, + {0x8d4a ,0xaf}, + {0x8d4b ,0x37}, + {0x8d4c ,0xae}, + {0x8d4d ,0x36}, + {0x8d4e ,0xad}, + {0x8d4f ,0x35}, + {0x8d50 ,0xac}, + {0x8d51 ,0x34}, + {0x8d52 ,0x90}, + {0x8d53 ,0x0e}, + {0x8d54 ,0x6a}, + {0x8d55 ,0x12}, + {0x8d56 ,0x0f}, + {0x8d57 ,0xa6}, + {0x8d58 ,0x8f}, + {0x8d59 ,0x37}, + {0x8d5a ,0x8e}, + {0x8d5b ,0x36}, + {0x8d5c ,0x8d}, + {0x8d5d ,0x35}, + {0x8d5e ,0x8c}, + {0x8d5f ,0x34}, + {0x8d60 ,0x90}, + {0x8d61 ,0x0e}, + {0x8d62 ,0x72}, + {0x8d63 ,0x12}, + {0x8d64 ,0x06}, + {0x8d65 ,0xdd}, + {0x8d66 ,0xef}, + {0x8d67 ,0x45}, + {0x8d68 ,0x37}, + {0x8d69 ,0xf5}, + {0x8d6a ,0x37}, + {0x8d6b ,0xee}, + {0x8d6c ,0x45}, + {0x8d6d ,0x36}, + {0x8d6e ,0xf5}, + {0x8d6f ,0x36}, + {0x8d70 ,0xed}, + {0x8d71 ,0x45}, + {0x8d72 ,0x35}, + {0x8d73 ,0xf5}, + {0x8d74 ,0x35}, + {0x8d75 ,0xec}, + {0x8d76 ,0x45}, + {0x8d77 ,0x34}, + {0x8d78 ,0xf5}, + {0x8d79 ,0x34}, + {0x8d7a ,0xe4}, + {0x8d7b ,0xf5}, + {0x8d7c ,0x22}, + {0x8d7d ,0xf5}, + {0x8d7e ,0x23}, + {0x8d7f ,0x85}, + {0x8d80 ,0x37}, + {0x8d81 ,0x31}, + {0x8d82 ,0x85}, + {0x8d83 ,0x36}, + {0x8d84 ,0x30}, + {0x8d85 ,0x85}, + {0x8d86 ,0x35}, + {0x8d87 ,0x2f}, + {0x8d88 ,0x85}, + {0x8d89 ,0x34}, + {0x8d8a ,0x2e}, + {0x8d8b ,0x12}, + {0x8d8c ,0x0f}, + {0x8d8d ,0x63}, + {0x8d8e ,0xe4}, + {0x8d8f ,0xf5}, + {0x8d90 ,0x22}, + {0x8d91 ,0xf5}, + {0x8d92 ,0x23}, + {0x8d93 ,0x90}, + {0x8d94 ,0x0e}, + {0x8d95 ,0x72}, + {0x8d96 ,0x12}, + {0x8d97 ,0x0f}, + {0x8d98 ,0x9a}, + {0x8d99 ,0x12}, + {0x8d9a ,0x0f}, + {0x8d9b ,0x63}, + {0x8d9c ,0xe4}, + {0x8d9d ,0xf5}, + {0x8d9e ,0x22}, + {0x8d9f ,0xf5}, + {0x8da0 ,0x23}, + {0x8da1 ,0x90}, + {0x8da2 ,0x0e}, + {0x8da3 ,0x6e}, + {0x8da4 ,0x12}, + {0x8da5 ,0x0f}, + {0x8da6 ,0x9a}, + {0x8da7 ,0x02}, + {0x8da8 ,0x0f}, + {0x8da9 ,0x63}, + {0x8daa ,0xae}, + {0x8dab ,0x35}, + {0x8dac ,0xaf}, + {0x8dad ,0x36}, + {0x8dae ,0xe4}, + {0x8daf ,0xfd}, + {0x8db0 ,0xed}, + {0x8db1 ,0xc3}, + {0x8db2 ,0x95}, + {0x8db3 ,0x37}, + {0x8db4 ,0x50}, + {0x8db5 ,0x33}, + {0x8db6 ,0x12}, + {0x8db7 ,0x0f}, + {0x8db8 ,0xec}, + {0x8db9 ,0xe4}, + {0x8dba ,0x93}, + {0x8dbb ,0xf5}, + {0x8dbc ,0x38}, + {0x8dbd ,0x74}, + {0x8dbe ,0x01}, + {0x8dbf ,0x93}, + {0x8dc0 ,0xf5}, + {0x8dc1 ,0x39}, + {0x8dc2 ,0x45}, + {0x8dc3 ,0x38}, + {0x8dc4 ,0x60}, + {0x8dc5 ,0x23}, + {0x8dc6 ,0x85}, + {0x8dc7 ,0x39}, + {0x8dc8 ,0x82}, + {0x8dc9 ,0x85}, + {0x8dca ,0x38}, + {0x8dcb ,0x83}, + {0x8dcc ,0xe0}, + {0x8dcd ,0xfc}, + {0x8dce ,0x12}, + {0x8dcf ,0x0f}, + {0x8dd0 ,0xec}, + {0x8dd1 ,0x74}, + {0x8dd2 ,0x03}, + {0x8dd3 ,0x93}, + {0x8dd4 ,0x52}, + {0x8dd5 ,0x04}, + {0x8dd6 ,0x12}, + {0x8dd7 ,0x0f}, + {0x8dd8 ,0xec}, + {0x8dd9 ,0x74}, + {0x8dda ,0x02}, + {0x8ddb ,0x93}, + {0x8ddc ,0x42}, + {0x8ddd ,0x04}, + {0x8dde ,0x85}, + {0x8ddf ,0x39}, + {0x8de0 ,0x82}, + {0x8de1 ,0x85}, + {0x8de2 ,0x38}, + {0x8de3 ,0x83}, + {0x8de4 ,0xec}, + {0x8de5 ,0xf0}, + {0x8de6 ,0x0d}, + {0x8de7 ,0x80}, + {0x8de8 ,0xc7}, + {0x8de9 ,0x22}, + {0x8dea ,0xc0}, + {0x8deb ,0xe0}, + {0x8dec ,0xc0}, + {0x8ded ,0x83}, + {0x8dee ,0xc0}, + {0x8def ,0x82}, + {0x8df0 ,0x90}, + {0x8df1 ,0x3f}, + {0x8df2 ,0x0d}, + {0x8df3 ,0xe0}, + {0x8df4 ,0xf5}, + {0x8df5 ,0x33}, + {0x8df6 ,0xe5}, + {0x8df7 ,0x33}, + {0x8df8 ,0xf0}, + {0x8df9 ,0xd0}, + {0x8dfa ,0x82}, + {0x8dfb ,0xd0}, + {0x8dfc ,0x83}, + {0x8dfd ,0xd0}, + {0x8dfe ,0xe0}, + {0x8dff ,0x32}, + {0x8e00 ,0x12}, + {0x8e01 ,0x04}, + {0x8e02 ,0x13}, + {0x8e03 ,0x10}, + {0x8e04 ,0x01}, + {0x8e05 ,0x03}, + {0x8e06 ,0x4f}, + {0x8e07 ,0x56}, + {0x8e08 ,0x54}, + {0x8e09 ,0x20}, + {0x8e0a ,0x20}, + {0x8e0b ,0x20}, + {0x8e0c ,0x20}, + {0x8e0d ,0x20}, + {0x8e0e ,0x13}, + {0x8e0f ,0x01}, + {0x8e10 ,0x10}, + {0x8e11 ,0x01}, + {0x8e12 ,0x56}, + {0x8e13 ,0x40}, + {0x8e14 ,0x1a}, + {0x8e15 ,0x30}, + {0x8e16 ,0x29}, + {0x8e17 ,0x7e}, + {0x8e18 ,0x00}, + {0x8e19 ,0x30}, + {0x8e1a ,0x04}, + {0x8e1b ,0x20}, + {0x8e1c ,0xdf}, + {0x8e1d ,0x30}, + {0x8e1e ,0x05}, + {0x8e1f ,0x40}, + {0x8e20 ,0xbf}, + {0x8e21 ,0x50}, + {0x8e22 ,0x03}, + {0x8e23 ,0x00}, + {0x8e24 ,0xfd}, + {0x8e25 ,0x50}, + {0x8e26 ,0x27}, + {0x8e27 ,0x01}, + {0x8e28 ,0xfe}, + {0x8e29 ,0x60}, + {0x8e2a ,0x00}, + {0x8e2b ,0x11}, + {0x8e2c ,0x00}, + {0x8e2d ,0x3f}, + {0x8e2e ,0x05}, + {0x8e2f ,0x30}, + {0x8e30 ,0x00}, + {0x8e31 ,0x3f}, + {0x8e32 ,0x06}, + {0x8e33 ,0x22}, + {0x8e34 ,0x00}, + {0x8e35 ,0x3f}, + {0x8e36 ,0x01}, + {0x8e37 ,0x2a}, + {0x8e38 ,0x00}, + {0x8e39 ,0x3f}, + {0x8e3a ,0x02}, + {0x8e3b ,0x00}, + {0x8e3c ,0x00}, + {0x8e3d ,0x36}, + {0x8e3e ,0x06}, + {0x8e3f ,0x07}, + {0x8e40 ,0x00}, + {0x8e41 ,0x3f}, + {0x8e42 ,0x0b}, + {0x8e43 ,0x0f}, + {0x8e44 ,0xf0}, + {0x8e45 ,0x00}, + {0x8e46 ,0x00}, + {0x8e47 ,0x00}, + {0x8e48 ,0x00}, + {0x8e49 ,0x30}, + {0x8e4a ,0x01}, + {0x8e4b ,0x40}, + {0x8e4c ,0xbf}, + {0x8e4d ,0x30}, + {0x8e4e ,0x01}, + {0x8e4f ,0x00}, + {0x8e50 ,0xbf}, + {0x8e51 ,0x30}, + {0x8e52 ,0x29}, + {0x8e53 ,0x70}, + {0x8e54 ,0x00}, + {0x8e55 ,0x3a}, + {0x8e56 ,0x00}, + {0x8e57 ,0x00}, + {0x8e58 ,0xff}, + {0x8e59 ,0x3a}, + {0x8e5a ,0x00}, + {0x8e5b ,0x00}, + {0x8e5c ,0xff}, + {0x8e5d ,0x36}, + {0x8e5e ,0x03}, + {0x8e5f ,0x36}, + {0x8e60 ,0x02}, + {0x8e61 ,0x41}, + {0x8e62 ,0x44}, + {0x8e63 ,0x58}, + {0x8e64 ,0x20}, + {0x8e65 ,0x18}, + {0x8e66 ,0x10}, + {0x8e67 ,0x0a}, + {0x8e68 ,0x04}, + {0x8e69 ,0x04}, + {0x8e6a ,0x00}, + {0x8e6b ,0x03}, + {0x8e6c ,0xff}, + {0x8e6d ,0x64}, + {0x8e6e ,0x00}, + {0x8e6f ,0x00}, + {0x8e70 ,0x80}, + {0x8e71 ,0x00}, + {0x8e72 ,0x00}, + {0x8e73 ,0x00}, + {0x8e74 ,0x00}, + {0x8e75 ,0x00}, + {0x8e76 ,0x00}, + {0x8e77 ,0x02}, + {0x8e78 ,0x04}, + {0x8e79 ,0x06}, + {0x8e7a ,0x06}, + {0x8e7b ,0x00}, + {0x8e7c ,0x02}, + {0x8e7d ,0x60}, + {0x8e7e ,0x00}, + {0x8e7f ,0x70}, + {0x8e80 ,0x50}, + {0x8e81 ,0x3c}, + {0x8e82 ,0x28}, + {0x8e83 ,0x1e}, + {0x8e84 ,0x10}, + {0x8e85 ,0x10}, + {0x8e86 ,0x50}, + {0x8e87 ,0x2d}, + {0x8e88 ,0x28}, + {0x8e89 ,0x16}, + {0x8e8a ,0x10}, + {0x8e8b ,0x10}, + {0x8e8c ,0x02}, + {0x8e8d ,0x00}, + {0x8e8e ,0x10}, + {0x8e8f ,0x30}, + {0x8e90 ,0x0a}, + {0x8e91 ,0x04}, + {0x8e92 ,0x05}, + {0x8e93 ,0x08}, + {0x8e94 ,0x64}, + {0x8e95 ,0x18}, + {0x8e96 ,0x05}, + {0x8e97 ,0x01}, + {0x8e98 ,0x00}, + {0x8e99 ,0xa5}, + {0x8e9a ,0x5a}, + {0x8e9b ,0x00}, + {0x8e9c ,0x78}, + {0x8e9d ,0xbe}, + {0x8e9e ,0xe6}, + {0x8e9f ,0xd3}, + {0x8ea0 ,0x08}, + {0x8ea1 ,0xff}, + {0x8ea2 ,0xe6}, + {0x8ea3 ,0x64}, + {0x8ea4 ,0x80}, + {0x8ea5 ,0xf8}, + {0x8ea6 ,0xef}, + {0x8ea7 ,0x64}, + {0x8ea8 ,0x80}, + {0x8ea9 ,0x98}, + {0x8eaa ,0x22}, + {0x8eab ,0x78}, + {0x8eac ,0xc0}, + {0x8ead ,0xa6}, + {0x8eae ,0x07}, + {0x8eaf ,0x78}, + {0x8eb0 ,0xbd}, + {0x8eb1 ,0xd3}, + {0x8eb2 ,0xe6}, + {0x8eb3 ,0x64}, + {0x8eb4 ,0x80}, + {0x8eb5 ,0x94}, + {0x8eb6 ,0x80}, + {0x8eb7 ,0x22}, + {0x8eb8 ,0x93}, + {0x8eb9 ,0xff}, + {0x8eba ,0x7e}, + {0x8ebb ,0x00}, + {0x8ebc ,0xe6}, + {0x8ebd ,0xfc}, + {0x8ebe ,0x08}, + {0x8ebf ,0xe6}, + {0x8ec0 ,0xfd}, + {0x8ec1 ,0x12}, + {0x8ec2 ,0x05}, + {0x8ec3 ,0x22}, + {0x8ec4 ,0x78}, + {0x8ec5 ,0xc1}, + {0x8ec6 ,0xe6}, + {0x8ec7 ,0xfc}, + {0x8ec8 ,0x08}, + {0x8ec9 ,0xe6}, + {0x8eca ,0xfd}, + {0x8ecb ,0xd3}, + {0x8ecc ,0xef}, + {0x8ecd ,0x9d}, + {0x8ece ,0xee}, + {0x8ecf ,0x9c}, + {0x8ed0 ,0x22}, + {0x8ed1 ,0x78}, + {0x8ed2 ,0xbf}, + {0x8ed3 ,0xa6}, + {0x8ed4 ,0x07}, + {0x8ed5 ,0x08}, + {0x8ed6 ,0xd3}, + {0x8ed7 ,0xe6}, + {0x8ed8 ,0x64}, + {0x8ed9 ,0x80}, + {0x8eda ,0x94}, + {0x8edb ,0x80}, + {0x8edc ,0x22}, + {0x8edd ,0x78}, + {0x8ede ,0xc0}, + {0x8edf ,0xa6}, + {0x8ee0 ,0x07}, + {0x8ee1 ,0xc3}, + {0x8ee2 ,0x18}, + {0x8ee3 ,0xe6}, + {0x8ee4 ,0x64}, + {0x8ee5 ,0x80}, + {0x8ee6 ,0x94}, + {0x8ee7 ,0xb3}, + {0x8ee8 ,0x22}, + {0x8ee9 ,0x78}, + {0x8eea ,0xbf}, + {0x8eeb ,0xa6}, + {0x8eec ,0x07}, + {0x8eed ,0xc3}, + {0x8eee ,0x08}, + {0x8eef ,0xe6}, + {0x8ef0 ,0x64}, + {0x8ef1 ,0x80}, + {0x8ef2 ,0x94}, + {0x8ef3 ,0xb3}, + {0x8ef4 ,0x22}, + {0x8ef5 ,0x25}, + {0x8ef6 ,0xe0}, + {0x8ef7 ,0x24}, + {0x8ef8 ,0x0a}, + {0x8ef9 ,0xf8}, + {0x8efa ,0xe6}, + {0x8efb ,0xfe}, + {0x8efc ,0x08}, + {0x8efd ,0xe6}, + {0x8efe ,0xff}, + {0x8eff ,0x22}, + {0x8f00 ,0xe5}, + {0x8f01 ,0x40}, + {0x8f02 ,0x24}, + {0x8f03 ,0xf2}, + {0x8f04 ,0xf5}, + {0x8f05 ,0x37}, + {0x8f06 ,0xe5}, + {0x8f07 ,0x3f}, + {0x8f08 ,0x34}, + {0x8f09 ,0x43}, + {0x8f0a ,0xf5}, + {0x8f0b ,0x36}, + {0x8f0c ,0xe5}, + {0x8f0d ,0x3e}, + {0x8f0e ,0x34}, + {0x8f0f ,0xa2}, + {0x8f10 ,0xf5}, + {0x8f11 ,0x35}, + {0x8f12 ,0xe5}, + {0x8f13 ,0x3d}, + {0x8f14 ,0x34}, + {0x8f15 ,0x28}, + {0x8f16 ,0xf5}, + {0x8f17 ,0x34}, + {0x8f18 ,0xe5}, + {0x8f19 ,0x37}, + {0x8f1a ,0xff}, + {0x8f1b ,0xe4}, + {0x8f1c ,0xfe}, + {0x8f1d ,0xfd}, + {0x8f1e ,0xfc}, + {0x8f1f ,0x78}, + {0x8f20 ,0x18}, + {0x8f21 ,0x12}, + {0x8f22 ,0x06}, + {0x8f23 ,0xca}, + {0x8f24 ,0x8f}, + {0x8f25 ,0x40}, + {0x8f26 ,0x8e}, + {0x8f27 ,0x3f}, + {0x8f28 ,0x8d}, + {0x8f29 ,0x3e}, + {0x8f2a ,0x8c}, + {0x8f2b ,0x3d}, + {0x8f2c ,0xe5}, + {0x8f2d ,0x37}, + {0x8f2e ,0x54}, + {0x8f2f ,0xa0}, + {0x8f30 ,0xff}, + {0x8f31 ,0xe5}, + {0x8f32 ,0x36}, + {0x8f33 ,0xfe}, + {0x8f34 ,0xe4}, + {0x8f35 ,0xfd}, + {0x8f36 ,0xfc}, + {0x8f37 ,0x78}, + {0x8f38 ,0x07}, + {0x8f39 ,0x12}, + {0x8f3a ,0x06}, + {0x8f3b ,0xb7}, + {0x8f3c ,0x78}, + {0x8f3d ,0x10}, + {0x8f3e ,0x12}, + {0x8f3f ,0x0f}, + {0x8f40 ,0xac}, + {0x8f41 ,0xe4}, + {0x8f42 ,0xff}, + {0x8f43 ,0xfe}, + {0x8f44 ,0xe5}, + {0x8f45 ,0x35}, + {0x8f46 ,0xfd}, + {0x8f47 ,0xe4}, + {0x8f48 ,0xfc}, + {0x8f49 ,0x78}, + {0x8f4a ,0x0e}, + {0x8f4b ,0x12}, + {0x8f4c ,0x06}, + {0x8f4d ,0xb7}, + {0x8f4e ,0x12}, + {0x8f4f ,0x0f}, + {0x8f50 ,0xaf}, + {0x8f51 ,0xe4}, + {0x8f52 ,0xff}, + {0x8f53 ,0xfe}, + {0x8f54 ,0xfd}, + {0x8f55 ,0xe5}, + {0x8f56 ,0x34}, + {0x8f57 ,0xfc}, + {0x8f58 ,0x78}, + {0x8f59 ,0x18}, + {0x8f5a ,0x12}, + {0x8f5b ,0x06}, + {0x8f5c ,0xb7}, + {0x8f5d ,0x78}, + {0x8f5e ,0x08}, + {0x8f5f ,0x12}, + {0x8f60 ,0x0f}, + {0x8f61 ,0xac}, + {0x8f62 ,0x22}, + {0x8f63 ,0xa2}, + {0x8f64 ,0xaf}, + {0x8f65 ,0x92}, + {0x8f66 ,0x32}, + {0x8f67 ,0xc2}, + {0x8f68 ,0xaf}, + {0x8f69 ,0xe5}, + {0x8f6a ,0x23}, + {0x8f6b ,0x45}, + {0x8f6c ,0x22}, + {0x8f6d ,0x90}, + {0x8f6e ,0x0e}, + {0x8f6f ,0x5d}, + {0x8f70 ,0x60}, + {0x8f71 ,0x0e}, + {0x8f72 ,0x12}, + {0x8f73 ,0x0f}, + {0x8f74 ,0xc7}, + {0x8f75 ,0xe0}, + {0x8f76 ,0xf5}, + {0x8f77 ,0x2c}, + {0x8f78 ,0x12}, + {0x8f79 ,0x0f}, + {0x8f7a ,0xc4}, + {0x8f7b ,0xe0}, + {0x8f7c ,0xf5}, + {0x8f7d ,0x2d}, + {0x8f7e ,0x80}, + {0x8f7f ,0x0c}, + {0x8f80 ,0x12}, + {0x8f81 ,0x0f}, + {0x8f82 ,0xc7}, + {0x8f83 ,0xe5}, + {0x8f84 ,0x30}, + {0x8f85 ,0xf0}, + {0x8f86 ,0x12}, + {0x8f87 ,0x0f}, + {0x8f88 ,0xc4}, + {0x8f89 ,0xe5}, + {0x8f8a ,0x31}, + {0x8f8b ,0xf0}, + {0x8f8c ,0xa2}, + {0x8f8d ,0x32}, + {0x8f8e ,0x92}, + {0x8f8f ,0xaf}, + {0x8f90 ,0x22}, + {0x8f91 ,0x8f}, + {0x8f92 ,0x3b}, + {0x8f93 ,0x8e}, + {0x8f94 ,0x3a}, + {0x8f95 ,0x8d}, + {0x8f96 ,0x39}, + {0x8f97 ,0x8c}, + {0x8f98 ,0x38}, + {0x8f99 ,0x22}, + {0x8f9a ,0x12}, + {0x8f9b ,0x06}, + {0x8f9c ,0xdd}, + {0x8f9d ,0x8f}, + {0x8f9e ,0x31}, + {0x8f9f ,0x8e}, + {0x8fa0 ,0x30}, + {0x8fa1 ,0x8d}, + {0x8fa2 ,0x2f}, + {0x8fa3 ,0x8c}, + {0x8fa4 ,0x2e}, + {0x8fa5 ,0x22}, + {0x8fa6 ,0x93}, + {0x8fa7 ,0xf9}, + {0x8fa8 ,0xf8}, + {0x8fa9 ,0x02}, + {0x8faa ,0x06}, + {0x8fab ,0xca}, + {0x8fac ,0x12}, + {0x8fad ,0x06}, + {0x8fae ,0xca}, + {0x8faf ,0xe5}, + {0x8fb0 ,0x40}, + {0x8fb1 ,0x2f}, + {0x8fb2 ,0xf5}, + {0x8fb3 ,0x40}, + {0x8fb4 ,0xe5}, + {0x8fb5 ,0x3f}, + {0x8fb6 ,0x3e}, + {0x8fb7 ,0xf5}, + {0x8fb8 ,0x3f}, + {0x8fb9 ,0xe5}, + {0x8fba ,0x3e}, + {0x8fbb ,0x3d}, + {0x8fbc ,0xf5}, + {0x8fbd ,0x3e}, + {0x8fbe ,0xe5}, + {0x8fbf ,0x3d}, + {0x8fc0 ,0x3c}, + {0x8fc1 ,0xf5}, + {0x8fc2 ,0x3d}, + {0x8fc3 ,0x22}, + {0x8fc4 ,0x90}, + {0x8fc5 ,0x0e}, + {0x8fc6 ,0x5f}, + {0x8fc7 ,0xe4}, + {0x8fc8 ,0x93}, + {0x8fc9 ,0xfe}, + {0x8fca ,0x74}, + {0x8fcb ,0x01}, + {0x8fcc ,0x93}, + {0x8fcd ,0xf5}, + {0x8fce ,0x82}, + {0x8fcf ,0x8e}, + {0x8fd0 ,0x83}, + {0x8fd1 ,0x22}, + {0x8fd2 ,0xd2}, + {0x8fd3 ,0x01}, + {0x8fd4 ,0xc2}, + {0x8fd5 ,0x02}, + {0x8fd6 ,0xe4}, + {0x8fd7 ,0xf5}, + {0x8fd8 ,0x1f}, + {0x8fd9 ,0xf5}, + {0x8fda ,0x1e}, + {0x8fdb ,0xd2}, + {0x8fdc ,0x35}, + {0x8fdd ,0xd2}, + {0x8fde ,0x33}, + {0x8fdf ,0x22}, + {0x8fe0 ,0x78}, + {0x8fe1 ,0x7f}, + {0x8fe2 ,0xe4}, + {0x8fe3 ,0xf6}, + {0x8fe4 ,0xd8}, + {0x8fe5 ,0xfd}, + {0x8fe6 ,0x75}, + {0x8fe7 ,0x81}, + {0x8fe8 ,0xcd}, + {0x8fe9 ,0x02}, + {0x8fea ,0x0c}, + {0x8feb ,0xc4}, + {0x8fec ,0x8f}, + {0x8fed ,0x82}, + {0x8fee ,0x8e}, + {0x8fef ,0x83}, + {0x8ff0 ,0x75}, + {0x8ff1 ,0xf0}, + {0x8ff2 ,0x04}, + {0x8ff3 ,0xed}, + {0x8ff4 ,0x02}, + {0x8ff5 ,0x07}, + {0x8ff6 ,0x06}, + {0x3022 ,0x00}, + {0x3023 ,0x00}, + {0x3024 ,0x00}, + {0x3025 ,0x00}, + {0x3026 ,0x00}, + {0x3027 ,0x00}, + {0x3028 ,0x00}, + {0x3029 ,0x7F}, + {0x3000 ,0x00}, + {0x3004, 0xff}, + {0x3005, 0xF7}, + + {0xffff, 0xff}, +}; + struct ov5642_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5058 @ struct ov5642 { const struct ov5642_datafmt *fmt; struct v4l2_rect crop_rect; struct v4l2_clk *clk; + struct clk *xvclk; /* blanking information */ int total_width; int total_height; + + bool is_ov5640; /* true means is ov5640. */ + + struct soc_camera_subdev_desc ssdd_dt; + struct gpio_desc *resetb_gpio; + struct gpio_desc *pwdn_gpio; }; static const struct ov5642_datafmt ov5642_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, }; static struct ov5642 *to_ov5642(const struct i2c_client *client) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5082 @ static struct ov5642 *to_ov5642(const st /* Find a data format by a pixel code in an array */ static const struct ov5642_datafmt - *ov5642_find_datafmt(enum v4l2_mbus_pixelcode code) + *ov5642_find_datafmt(u32 code) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5187 @ static int ov5642_write_array(struct i2c return 0; } +/* 5640 AFC commands + */ +#define WAIT_AFC_STATUS_OK_MILLI_SEC 100 + +#define AFC_COMMAND_SINGLE_FOCUS 0 +#define AFC_COMMAND_CONTINUE_FOCUS 1 +#define AFC_COMMAND_PAUSE_FOCUS 2 +#define AFC_COMMAND_RELEASE_FOCUS 3 + +static struct regval_list ov5640_afc_regs_single_focus[] = { + {0x3023, 0x1}, + {0x3022, 0x3}, + {0xffff, 0xff}, +}; +static struct regval_list ov5640_afc_regs_continue_focus[] = { + {0x3024, 0x1}, + {0x3022, 0x4}, + {0xffff, 0xff}, +}; +static struct regval_list ov5640_afc_regs_pause_focus[] = { + {0x3023, 0x1}, + {0x3022, 0x6}, + {0xffff, 0xff}, +}; +static struct regval_list ov5640_afc_regs_release_focus[] = { + {0x3023, 0x1}, + {0x3022, 0x8}, + {0xffff, 0xff}, +}; + +static int ov5640_afc_wait_status(struct i2c_client *client, u16 addr, u8 val) +{ + unsigned long timeout; + int ret; + u8 value; + + timeout = jiffies + WAIT_AFC_STATUS_OK_MILLI_SEC * HZ; + /* Wait until the AFC status is ok. */ + do { + ret = reg_read(client, addr, &value); + if (ret) { + dev_err(&client->dev, "OV5640 AFC: fail to read...\n"); + return ret; + } + + msleep(1); + } while (value != val && time_before(jiffies, timeout)); + + if (value != val) + dev_err(&client->dev, "OV5640 AFC: wait status: 0x%0x failed, get 0x%0x\n", + val, value); + + if (time_after(jiffies, timeout)) { + dev_err(&client->dev, "OV5640 AFC: timeout to wait status\n"); + return -ETIMEDOUT; + } else { + return 0; + } +} + +static int ov5640_afc_wait_init_done(struct i2c_client *client) +{ + return ov5640_afc_wait_status(client, 0x3029, 0x70); +} + +static int ov5640_afc_wait_command_status(struct i2c_client *client) +{ + return ov5640_afc_wait_status(client, 0x3023, 0); +} + +static int ov5640_afc_send_command(struct i2c_client *client, int afc_command) +{ + int ret = 0; + + switch (afc_command) { + case AFC_COMMAND_SINGLE_FOCUS: + ret = ov5642_write_array(client, ov5640_afc_regs_single_focus); + break; + case AFC_COMMAND_CONTINUE_FOCUS: + ret = ov5642_write_array(client, ov5640_afc_regs_continue_focus); + break; + case AFC_COMMAND_PAUSE_FOCUS: + ret = ov5642_write_array(client, ov5640_afc_regs_pause_focus); + break; + case AFC_COMMAND_RELEASE_FOCUS: + ret = ov5642_write_array(client, ov5640_afc_regs_release_focus); + break; + default: + return -EINVAL; /* error, then quit */ + }; + if (!ret) + ret = ov5640_afc_wait_command_status(client); + + if (ret < 0) + dev_err(&client->dev, "OV5640 AFC: fail to send afc command, error = %d!\n", ret); + + return ret; +} + static int ov5642_set_resolution(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5345 @ static int ov5642_try_fmt(struct v4l2_su struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code); + int i; - mf->width = priv->crop_rect.width; - mf->height = priv->crop_rect.height; + dev_dbg(&client->dev, "try_fmt: width = %d, height = %d\n", + mf->width, mf->height); if (!fmt) { mf->code = ov5642_colour_fmts[0].code; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5357 @ static int ov5642_try_fmt(struct v4l2_su mf->field = V4L2_FIELD_NONE; + if (!priv->is_ov5640) { + mf->width = priv->crop_rect.width; + mf->height = priv->crop_rect.height; + return 0; + } + + /* ov5640 */ + for (i = 0; i < ARRAY_SIZE(ov5640_support_sizes); i++) { + if (mf->width <= ov5640_support_sizes[i].width) + break; /* use this */ + } + + /* bigger than our max support size then use our max size */ + if (i == ARRAY_SIZE(ov5640_support_sizes)) + i = ARRAY_SIZE(ov5640_support_sizes) - 1; + + mf->width = priv->crop_rect.width = ov5640_support_sizes[i].width; + mf->height = priv->crop_rect.height = ov5640_support_sizes[i].height; + return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5389 @ static int ov5642_s_fmt(struct v4l2_subd if (!ov5642_find_datafmt(mf->code)) return -EINVAL; + dev_dbg(&client->dev, "set_fmt: width = %d, height = %d\n", + mf->width, mf->height); ov5642_try_fmt(sd, mf); priv->fmt = ov5642_find_datafmt(mf->code); + if (!priv->is_ov5640) + return 0; + + /* OV5640 */ + if (priv->crop_rect.width == 1280) + ov5642_write_array(client, ov5640_default_regs_finalise_960p); + else + ov5642_write_array(client, ov5640_default_regs_finalise); + return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5411 @ static int ov5642_g_fmt(struct v4l2_subd { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); + int i; const struct ov5642_datafmt *fmt = priv->fmt; mf->code = fmt->code; mf->colorspace = fmt->colorspace; - mf->width = priv->crop_rect.width; - mf->height = priv->crop_rect.height; mf->field = V4L2_FIELD_NONE; + if (!priv->is_ov5640) { + mf->width = priv->crop_rect.width; + mf->height = priv->crop_rect.height; + return 0; + } + + /* ov5640 */ + for (i = 0; i < ARRAY_SIZE(ov5640_support_sizes); i++) { + if (mf->width <= ov5640_support_sizes[i].width) + break; /* use this */ + } + + /* bigger than our max support size then use our max size */ + if (i == ARRAY_SIZE(ov5640_support_sizes)) + i = ARRAY_SIZE(ov5640_support_sizes) - 1; + + mf->width = ov5640_support_sizes[i].width; + mf->height = ov5640_support_sizes[i].height; + return 0; } static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov5642_colour_fmts)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5470 @ static int ov5642_s_crop(struct v4l2_sub priv->crop_rect.width = rect.width; priv->crop_rect.height = rect.height; + dev_dbg(&client->dev, "ov5642_s_crop(): width = %d, height = %d\n", + priv->crop_rect.width, priv->crop_rect.height); + + /* ov5640 */ + if (priv->is_ov5640) { + ret = ov5642_write_array(client, ov5640_default_regs_init); + if (!ret) + ret = ov5642_write_array(client, ov5640_default_regs_finalise); + if (!ret && rect.width == 1280) + ret = ov5642_write_array(client, ov5640_default_regs_finalise_960p); + return ret; + } + + /* ov5642 */ ret = ov5642_write_array(client, ov5642_default_regs_init); if (!ret) ret = ov5642_set_resolution(sd); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5524 @ static int ov5642_cropcap(struct v4l2_su static int ov5642_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov5642 *priv = to_ov5642(client); + cfg->type = V4L2_MBUS_CSI2; cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + + if (priv->is_ov5640) { + cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_HIGH; + cfg->type = V4L2_MBUS_PARALLEL; + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); + } + return 0; } +static int ov5642_hw_reset(struct device *dev); + static int ov5642_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5553 @ static int ov5642_s_power(struct v4l2_su struct ov5642 *priv = to_ov5642(client); int ret; - if (!on) + dev_dbg(&client->dev, "ov5642_s_power(): width = %d, height = %d\n", + priv->crop_rect.width, priv->crop_rect.height); + + if (!on) { + clk_disable_unprepare(priv->xvclk); return soc_camera_power_off(&client->dev, ssdd, priv->clk); + } - ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); + ret = clk_prepare_enable(priv->xvclk); if (ret < 0) return ret; + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); + if (ret < 0) { + clk_disable_unprepare(priv->xvclk); + return ret; + } + + /* Add reset when power on the camera according to the datasheet */ + ov5642_hw_reset(&client->dev); + + /* ov5640 */ + if (priv->is_ov5640) { + ret = ov5642_write_array(client, ov5640_default_regs_init); + if (!ret) + ret = ov5642_write_array(client, ov5640_default_regs_finalise); + if (!ret) { + /* Setup OV5640 Auto Focus Controller firmware */ + ret = ov5642_write_array(client, ov5640_afc_regs_init); + msleep(10); + } + if (!ret) + ret = ov5640_afc_wait_init_done(client); + + return ret; + } + + /* ov5642 */ ret = ov5642_write_array(client, ov5642_default_regs_init); if (!ret) ret = ov5642_set_resolution(sd); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5600 @ static int ov5642_s_power(struct v4l2_su return ret; } +static int ov5642_s_steram(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + if (enable) + /* Start AFC continue mode */ + ret = ov5640_afc_send_command(client, AFC_COMMAND_CONTINUE_FOCUS); + else + /* Rlease AFC */ + ret = ov5640_afc_send_command(client, AFC_COMMAND_RELEASE_FOCUS); + + return ret; +} + static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { .s_mbus_fmt = ov5642_s_fmt, .g_mbus_fmt = ov5642_g_fmt, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5624 @ static struct v4l2_subdev_video_ops ov56 .g_crop = ov5642_g_crop, .cropcap = ov5642_cropcap, .g_mbus_config = ov5642_g_mbus_config, + + .s_stream = ov5642_s_steram, }; static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5641 @ static struct v4l2_subdev_ops ov5642_sub .video = &ov5642_subdev_video_ops, }; +/* OF probe functions */ +static int ov5642_hw_power(struct device *dev, int on) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov5642 *priv = to_ov5642(client); + + dev_dbg(&client->dev, "%s: %s the camera\n", + __func__, on ? "ENABLE" : "DISABLE"); + + if (priv->pwdn_gpio) + gpiod_direction_output(priv->pwdn_gpio, !on); + + /* We need wait for ~1ms, then access the SCCB */ + if (on) + usleep_range(1000, 2000); + + return 0; +} + +static int ov5642_hw_reset(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov5642 *priv = to_ov5642(client); + + if (priv->resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv->resetb_gpio, 1); + usleep_range(1000, 3000); + gpiod_direction_output(priv->resetb_gpio, 0); + } + + /* We need wait for ~20ms, then access the SCCB */ + usleep_range(20000, 21000); + + return 0; +} + +static int ov5642_probe_dt(struct i2c_client *client, + struct ov5642 *priv) +{ + /* Request the reset GPIO deasserted */ + priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", + GPIOD_OUT_LOW); + if (!priv->resetb_gpio) + dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); + else if (IS_ERR(priv->resetb_gpio)) + return PTR_ERR(priv->resetb_gpio); + + /* Request the power down GPIO asserted */ + priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + if (!priv->pwdn_gpio) + dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); + else if (IS_ERR(priv->pwdn_gpio)) + return PTR_ERR(priv->pwdn_gpio); + + /* Initialize the soc_camera_subdev_desc */ + priv->ssdd_dt.power = ov5642_hw_power; + priv->ssdd_dt.reset = ov5642_hw_reset; + client->dev.platform_data = &priv->ssdd_dt; + + return 0; +} + static int ov5642_video_probe(struct i2c_client *client) { struct v4l2_subdev *subdev = i2c_get_clientdata(client); + struct ov5642 *priv = to_ov5642(client); int ret; u8 id_high, id_low; u16 id; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5732 @ static int ov5642_video_probe(struct i2c dev_info(&client->dev, "Chip ID 0x%04x detected\n", id); - if (id != 0x5642) { + switch (id) { + case 0x5640: + priv->is_ov5640 = true; /* fall through */ + case 0x5642: + break; + default: ret = -ENODEV; goto done; - } + }; ret = 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5756 @ static int ov5642_probe(struct i2c_clien struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!ssdd) { - dev_err(&client->dev, "OV5642: missing platform data!\n"); - return -EINVAL; - } - priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return -EPROBE_DEFER; + + if (!ssdd && !client->dev.of_node) { + dev_err(&client->dev, "OV5642: missing platform data!\n"); + ret = -EINVAL; + goto err_clk; + } + + if (!ssdd) { + ret = ov5642_probe_dt(client, priv); + if (ret) + goto err_clk; + } + + priv->xvclk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(priv->xvclk)) { + ret = PTR_ERR(priv->xvclk); + goto err_clk; + } + v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops); priv->fmt = &ov5642_colour_fmts[0]; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5793 @ static int ov5642_probe(struct i2c_clien priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH; priv->total_height = BLANKING_MIN_HEIGHT; - priv->clk = v4l2_clk_get(&client->dev, "mclk"); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); - ret = ov5642_video_probe(client); if (ret < 0) - v4l2_clk_put(priv->clk); + goto err_clk; + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) + goto err_clk; + + return 0; + +err_clk: + v4l2_clk_put(priv->clk); return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5813 @ static int ov5642_remove(struct i2c_clie struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct ov5642 *priv = to_ov5642(client); + v4l2_async_unregister_subdev(&priv->subdev); v4l2_clk_put(priv->clk); if (ssdd->free_bus) ssdd->free_bus(ssdd); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:5827 @ static const struct i2c_device_id ov5642 }; MODULE_DEVICE_TABLE(i2c, ov5642_id); +static const struct of_device_id ov5642_of_match[] = { + {.compatible = "ovti,ov5642", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ov5642_of_match); + static struct i2c_driver ov5642_i2c_driver = { .driver = { .name = "ov5642", + .of_match_table = of_match_ptr(ov5642_of_match), }, .probe = ov5642_probe, .remove = ov5642_remove, Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov6650.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov6650.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov6650.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:205 @ struct ov6650 { unsigned long pclk_limit; /* from host */ unsigned long pclk_max; /* from resolution and format */ struct v4l2_fract tpf; /* as requested with s_parm */ - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; -static enum v4l2_mbus_pixelcode ov6650_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_YVYU8_2X8, - V4L2_MBUS_FMT_VYUY8_2X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_Y8_1X8, +static u32 ov6650_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_Y8_1X8, }; /* read a register */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:558 @ static int ov6650_s_fmt(struct v4l2_subd .height = mf->height << half_scale, }, }; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; unsigned long mclk, pclk; u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; int ret; /* select color matrix configuration for given color encoding */ switch (code) { - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; coma_set |= COMA_BW; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; coma_set |= COMA_WORD_SWAP; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | COMA_BYTE_SWAP; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); if (half_scale) { coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:590 @ static int ov6650_s_fmt(struct v4l2_subd coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; } break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); if (half_scale) { coma_mask |= COMA_RGB | COMA_BW; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:600 @ static int ov6650_s_fmt(struct v4l2_subd coma_set |= COMA_BYTE_SWAP; } break; - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; coma_set |= COMA_RAW_RGB | COMA_RGB; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:611 @ static int ov6650_s_fmt(struct v4l2_subd } priv->code = code; - if (code == V4L2_MBUS_FMT_Y8_1X8 || - code == V4L2_MBUS_FMT_SBGGR8_1X8) { + if (code == MEDIA_BUS_FMT_Y8_1X8 || + code == MEDIA_BUS_FMT_SBGGR8_1X8) { coml_mask = COML_ONE_CHANNEL; coml_set = 0; priv->pclk_max = 4000000; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:622 @ static int ov6650_s_fmt(struct v4l2_subd priv->pclk_max = 8000000; } - if (code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (code == MEDIA_BUS_FMT_SBGGR8_1X8) priv->colorspace = V4L2_COLORSPACE_SRGB; else if (code != 0) priv->colorspace = V4L2_COLORSPACE_JPEG; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:700 @ static int ov6650_try_fmt(struct v4l2_su mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_Y10_1X10: - mf->code = V4L2_MBUS_FMT_Y8_1X8; - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_Y10_1X10: + mf->code = MEDIA_BUS_FMT_Y8_1X8; + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; break; default: - mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; - case V4L2_MBUS_FMT_SBGGR8_1X8: + mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; + case MEDIA_BUS_FMT_SBGGR8_1X8: mf->colorspace = V4L2_COLORSPACE_SRGB; break; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:720 @ static int ov6650_try_fmt(struct v4l2_su } static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov6650_codes)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1016 @ static int ov6650_probe(struct i2c_clien priv->rect.width = W_CIF; priv->rect.height = H_CIF; priv->half_scale = false; - priv->code = V4L2_MBUS_FMT_YUYV8_2X8; + priv->code = MEDIA_BUS_FMT_YUYV8_2X8; priv->colorspace = V4L2_COLORSPACE_JPEG; priv->clk = v4l2_clk_get(&client->dev, "mclk"); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov772x.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov772x.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov772x.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:379 @ */ struct ov772x_color_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u8 dsp3; u8 dsp4; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:411 @ struct ov772x_priv { */ static const struct ov772x_color_format ov772x_cfmts[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:419 @ static const struct ov772x_color_format .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = UV_ON, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:427 @ static const struct ov772x_color_format .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:435 @ static const struct ov772x_color_format .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:443 @ static const struct ov772x_color_format .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:451 @ static const struct ov772x_color_format .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:459 @ static const struct ov772x_color_format .com7 = FMT_RGB565 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:471 @ static const struct ov772x_color_format * regardless of the COM7 value. We can thus only support 10-bit * Bayer until someone figures it out. */ - .code = V4L2_MBUS_FMT_SBGGR10_1X10, + .code = MEDIA_BUS_FMT_SBGGR10_1X10, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_RAW10, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:993 @ static struct v4l2_subdev_core_ops ov772 }; static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov772x_cfmts)) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov7740.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov7740.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * ov7740 Camera Driver + * + * Copyright (C) 2013 Josh Wu <josh.wu@atmel.com> + * + * Based on ov2640, ov772x, ov9640 drivers and previous non merged implementations. + * + * 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 <linux/init.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/slab.h> +#include <linux/v4l2-mediabus.h> +#include <linux/videodev2.h> + +#include <media/soc_camera.h> +#include <media/v4l2-clk.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-subdev.h> + +#define VAL_SET(x, mask, rshift, lshift) \ + ((((x) >> rshift) & mask) << lshift) + +#define REG0C 0x0C /* Register 0C */ +#define REG0C_HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF */ +#define REG0C_VFLIP_IMG 0x80 /* Vertical flip image ON/OFF */ + +/* + * ID + */ +#define PID 0x0A /* Product ID Number MSB */ +#define VER 0x0B /* Product ID Number LSB */ +#define MIDH 0x1C /* Manufacturer ID byte - high */ +#define MIDL 0x1D /* Manufacturer ID byte - low */ + +#define PID_OV7740 0x7742 +#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF)) + +/* + * Struct + */ +struct regval_list { + u8 reg_num; + u8 value; +}; + +/* Supported resolutions */ +enum ov7740_width { + W_VGA = 640, +}; + +enum ov7740_height { + H_VGA = 480, +}; + +struct ov7740_win_size { + char *name; + enum ov7740_width width; + enum ov7740_height height; + const struct regval_list *regs; +}; + + +struct ov7740_priv { + struct v4l2_subdev subdev; + struct v4l2_ctrl_handler hdl; + u32 cfmt_code; + struct v4l2_clk *clk; + struct clk *xvclk; + const struct ov7740_win_size *win; + + struct soc_camera_subdev_desc ssdd_dt; + struct gpio_desc *resetb_gpio; + struct gpio_desc *pwdn_gpio; +}; + +/* + * Registers settings + */ + +#define ENDMARKER { 0xff, 0xff } + +static const struct regval_list ov7740_init_regs[] = { + {0x55 ,0x40}, + {0x11 ,0x02}, + + {0x12 ,0x00}, + {0xd5 ,0x10}, + {0x0c ,0x12}, + {0x0d ,0x34}, + {0x17 ,0x25}, + {0x18 ,0xa0}, + {0x19 ,0x03}, + {0x1a ,0xf0}, + {0x1b ,0x89}, + {0x22 ,0x03}, + {0x29 ,0x18}, + {0x2b ,0xf8}, + {0x2c ,0x01}, + {0x31 ,0xa0}, + {0x32 ,0xf0}, + {0x33 ,0xc4}, + {0x35 ,0x05}, + {0x36 ,0x3f}, + {0x04 ,0x60}, + {0x27 ,0x80}, + {0x3d ,0x0f}, + {0x3e ,0x80}, + {0x3f ,0x40}, + {0x40 ,0x7f}, + {0x41 ,0x6a}, + {0x42 ,0x29}, + {0x44 ,0x22}, + {0x45 ,0x41}, + {0x47 ,0x02}, + {0x49 ,0x64}, + {0x4a ,0xa1}, + {0x4b ,0x40}, + {0x4c ,0x1a}, + {0x4d ,0x50}, + {0x4e ,0x13}, + {0x64 ,0x00}, + {0x67 ,0x88}, + {0x68 ,0x1a}, + + {0x14 ,0x28}, + {0x24 ,0x3c}, + {0x25 ,0x30}, + {0x26 ,0x72}, + {0x50 ,0x97}, + {0x51 ,0x1f}, + {0x52 ,0x00}, + {0x53 ,0x00}, + {0x20 ,0x00}, + {0x21 ,0xcf}, + {0x50, 0x4b}, + {0x38 ,0x14}, + {0xe9 ,0x00}, + {0x56 ,0x55}, + {0x57 ,0xff}, + {0x58 ,0xff}, + {0x59 ,0xff}, + {0x5f ,0x04}, + {0xec ,0x00}, + {0x13 ,0xff}, + + {0x80 ,0x7f}, + {0x81 ,0x3f}, + {0x82 ,0x32}, + {0x83 ,0x01}, + {0x38 ,0x11}, + {0x84 ,0x70}, + {0x85 ,0x00}, + {0x86 ,0x03}, + {0x87 ,0x01}, + {0x88 ,0x05}, + {0x89 ,0x30}, + {0x8d ,0x30}, + {0x8f ,0x85}, + {0x93 ,0x30}, + {0x95 ,0x85}, + {0x99 ,0x30}, + {0x9b ,0x85}, + + {0x9c ,0x08}, + {0x9d ,0x12}, + {0x9e ,0x23}, + {0x9f ,0x45}, + {0xa0 ,0x55}, + {0xa1 ,0x64}, + {0xa2 ,0x72}, + {0xa3 ,0x7f}, + {0xa4 ,0x8b}, + {0xa5 ,0x95}, + {0xa6 ,0xa7}, + {0xa7 ,0xb5}, + {0xa8 ,0xcb}, + {0xa9 ,0xdd}, + {0xaa ,0xec}, + {0xab ,0x1a}, + + {0xce ,0x78}, + {0xcf ,0x6e}, + {0xd0 ,0x0a}, + {0xd1 ,0x0c}, + {0xd2 ,0x84}, + {0xd3 ,0x90}, + {0xd4 ,0x1e}, + + {0x5a ,0x24}, + {0x5b ,0x1f}, + {0x5c ,0x88}, + {0x5d ,0x60}, + + {0xac ,0x6e}, + {0xbe ,0xff}, + {0xbf ,0x00}, + + {0x0f ,0x1d}, + {0x0f ,0x1f}, + ENDMARKER, +}; + +static const struct regval_list ov7740_vga_regs[] = { + /* Initial registers is for vga format, no setting needed */ + ENDMARKER, +}; + +#define OV7740_SIZE(n, w, h, r) \ + {.name = n, .width = w , .height = h, .regs = r } + +static const struct ov7740_win_size ov7740_supported_win_sizes[] = { + OV7740_SIZE("VGA", W_VGA, H_VGA, ov7740_vga_regs), +}; + +static u32 ov7740_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, +}; + +/* + * General functions + */ +static struct ov7740_priv *to_ov7740(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct ov7740_priv, + subdev); +} + +static int ov7740_write_array(struct i2c_client *client, + const struct regval_list *vals) +{ + int ret; + + while ((vals->reg_num != 0xff) || (vals->value != 0xff)) { + ret = i2c_smbus_write_byte_data(client, + vals->reg_num, vals->value); + dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x", + vals->reg_num, vals->value); + + if (ret < 0) { + dev_err(&client->dev, "array: 0x%02x, 0x%02x write failed", + vals->reg_num, vals->value); + return ret; + } + vals++; + } + return 0; +} + +static int ov7740_mask_set(struct i2c_client *client, + u8 reg, u8 mask, u8 set) +{ + s32 val = i2c_smbus_read_byte_data(client, reg); + if (val < 0) + return val; + + val &= ~mask; + val |= set & mask; + + dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val); + + return i2c_smbus_write_byte_data(client, reg, val); +} + +static int ov7740_reset(struct i2c_client *client) +{ + int ret; + const struct regval_list reset_seq[] = { + {0x12 ,0x80}, + ENDMARKER, + }; + + ret = ov7740_write_array(client, reset_seq); + if (ret) + goto err; + + msleep(5); +err: + dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret); + return ret; +} + +/* + * soc_camera_ops functions + */ +static int ov7740_s_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +static int ov7740_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct v4l2_subdev *sd = + &container_of(ctrl->handler, struct ov7740_priv, hdl)->subdev; + struct i2c_client *client = v4l2_get_subdevdata(sd); + u8 val; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + val = ctrl->val ? REG0C_VFLIP_IMG : 0x00; + return ov7740_mask_set(client, REG0C, REG0C_VFLIP_IMG, val); + case V4L2_CID_HFLIP: + val = ctrl->val ? REG0C_HFLIP_IMG : 0x00; + return ov7740_mask_set(client, REG0C, REG0C_HFLIP_IMG, val); + } + + return -EINVAL; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ov7740_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + reg->size = 1; + if (reg->reg > 0xff) + return -EINVAL; + + ret = i2c_smbus_read_byte_data(client, reg->reg); + if (ret < 0) + return ret; + + reg->val = ret; + + return 0; +} + +static int ov7740_s_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg > 0xff || + reg->val > 0xff) + return -EINVAL; + + return i2c_smbus_write_byte_data(client, reg->reg, reg->val); +} +#endif + +static int ov7740_s_power(struct v4l2_subdev *sd, int on) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov7740_priv *priv = to_ov7740(client); + + if (on) + clk_prepare_enable(priv->xvclk); + else + clk_disable_unprepare(priv->xvclk); + + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); +} + +/* Select the nearest higher resolution for capture */ +static const struct ov7740_win_size *ov7740_select_win(u32 *width, u32 *height) +{ + int i, default_size = ARRAY_SIZE(ov7740_supported_win_sizes) - 1; + + for (i = 0; i < ARRAY_SIZE(ov7740_supported_win_sizes); i++) { + if (ov7740_supported_win_sizes[i].width >= *width && + ov7740_supported_win_sizes[i].height >= *height) { + *width = ov7740_supported_win_sizes[i].width; + *height = ov7740_supported_win_sizes[i].height; + return &ov7740_supported_win_sizes[i]; + } + } + + *width = ov7740_supported_win_sizes[default_size].width; + *height = ov7740_supported_win_sizes[default_size].height; + return &ov7740_supported_win_sizes[default_size]; +} + +static int ov7740_set_params(struct i2c_client *client, u32 *width, u32 *height, + u32 code) +{ + struct ov7740_priv *priv = to_ov7740(client); + int ret; + + /* select win */ + priv->win = ov7740_select_win(width, height); + + /* select format */ + priv->cfmt_code = 0; + switch (code) { + default: + case MEDIA_BUS_FMT_YUYV8_2X8: + dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__); + } + + /* reset hardware */ + ov7740_reset(client); + + /* initialize the sensor with default data */ + dev_dbg(&client->dev, "%s: Init default", __func__); + ret = ov7740_write_array(client, ov7740_init_regs); + if (ret < 0) + goto err; + + priv->cfmt_code = code; + *width = priv->win->width; + *height = priv->win->height; + + return 0; + +err: + dev_err(&client->dev, "%s: Error %d", __func__, ret); + ov7740_reset(client); + priv->win = NULL; + + return ret; +} + +static int ov7740_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov7740_priv *priv = to_ov7740(client); + + if (!priv->win) { + u32 width = W_VGA, height = H_VGA; + priv->win = ov7740_select_win(&width, &height); + priv->cfmt_code = MEDIA_BUS_FMT_YUYV8_2X8; + } + + mf->width = priv->win->width; + mf->height = priv->win->height; + mf->code = priv->cfmt_code; + + switch (mf->code) { + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + mf->colorspace = V4L2_COLORSPACE_SRGB; + break; + default: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + mf->colorspace = V4L2_COLORSPACE_JPEG; + } + mf->field = V4L2_FIELD_NONE; + + return 0; +} + +static int ov7740_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + + switch (mf->code) { + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + mf->colorspace = V4L2_COLORSPACE_SRGB; + break; + default: + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + mf->colorspace = V4L2_COLORSPACE_JPEG; + } + + ret = ov7740_set_params(client, &mf->width, &mf->height, mf->code); + + return ret; +} + +static int ov7740_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + /* + * select suitable win, but don't store it + */ + ov7740_select_win(&mf->width, &mf->height); + + mf->field = V4L2_FIELD_NONE; + + switch (mf->code) { + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + mf->colorspace = V4L2_COLORSPACE_SRGB; + break; + default: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + mf->colorspace = V4L2_COLORSPACE_JPEG; + } + + return 0; +} + +static int ov7740_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + u32 *code) +{ + if (index >= ARRAY_SIZE(ov7740_codes)) + return -EINVAL; + + *code = ov7740_codes[index]; + return 0; +} + +static int ov7740_video_probe(struct i2c_client *client) +{ + struct ov7740_priv *priv = to_ov7740(client); + u8 pid, ver, midh, midl; + const char *devname; + int ret; + + ret = ov7740_s_power(&priv->subdev, 1); + if (ret < 0) + return ret; + + /* + * check and show product ID and manufacturer ID + */ + pid = i2c_smbus_read_byte_data(client, PID); + ver = i2c_smbus_read_byte_data(client, VER); + midh = i2c_smbus_read_byte_data(client, MIDH); + midl = i2c_smbus_read_byte_data(client, MIDL); + + switch (VERSION(pid, ver)) { + case PID_OV7740: + devname = "ov7740"; + break; + default: + dev_err(&client->dev, + "Product ID error %x:%x\n", pid, ver); + ret = -ENODEV; + goto done; + } + + dev_info(&client->dev, + "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", + devname, pid, ver, midh, midl); + + ret = v4l2_ctrl_handler_setup(&priv->hdl); + +done: + ov7740_s_power(&priv->subdev, 0); + return ret; +} + +static const struct v4l2_ctrl_ops ov7740_ctrl_ops = { + .s_ctrl = ov7740_s_ctrl, +}; + +static struct v4l2_subdev_core_ops ov7740_subdev_core_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ov7740_g_register, + .s_register = ov7740_s_register, +#endif + .s_power = ov7740_s_power, +}; + +static int ov7740_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + + cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_HIGH; + cfg->type = V4L2_MBUS_PARALLEL; + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); + + return 0; +} + +static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = { + .s_stream = ov7740_s_stream, + .g_mbus_fmt = ov7740_g_fmt, + .s_mbus_fmt = ov7740_s_fmt, + .try_mbus_fmt = ov7740_try_fmt, + .enum_mbus_fmt = ov7740_enum_fmt, + .g_mbus_config = ov7740_g_mbus_config, +}; + +static struct v4l2_subdev_ops ov7740_subdev_ops = { + .core = &ov7740_subdev_core_ops, + .video = &ov7740_subdev_video_ops, +}; + +/* OF probe functions */ +static int ov7740_hw_power(struct device *dev, int on) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov7740_priv *priv = to_ov7740(client); + + dev_dbg(&client->dev, "%s: %s the camera\n", + __func__, on ? "ENABLE" : "DISABLE"); + + if (priv->pwdn_gpio) + gpiod_direction_output(priv->pwdn_gpio, !on); + + /* We need wait for ~1ms, then access the SCCB */ + if (on) + usleep_range(1000, 2000); + + return 0; +} + +static int ov7740_hw_reset(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov7740_priv *priv = to_ov7740(client); + + if (priv->resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv->resetb_gpio, 1); + usleep_range(1000, 3000); + gpiod_direction_output(priv->resetb_gpio, 0); + } + + /* We need wait for ~20ms, then access the SCCB */ + usleep_range(20000, 21000); + + return 0; +} + +static int ov7740_probe_dt(struct i2c_client *client, + struct ov7740_priv *priv) +{ + /* Request the reset GPIO deasserted */ + priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", + GPIOD_OUT_LOW); + if (!priv->resetb_gpio) + dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); + else if (IS_ERR(priv->resetb_gpio)) + return PTR_ERR(priv->resetb_gpio); + + /* Request the power down GPIO asserted */ + priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + if (!priv->pwdn_gpio) + dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); + else if (IS_ERR(priv->pwdn_gpio)) + return PTR_ERR(priv->pwdn_gpio); + + /* Initialize the soc_camera_subdev_desc */ + priv->ssdd_dt.power = ov7740_hw_power; + priv->ssdd_dt.reset = ov7740_hw_reset; + client->dev.platform_data = &priv->ssdd_dt; + + return 0; +} + +/* + * i2c_driver functions + */ +static int ov7740_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ov7740_priv *priv; + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + int ret; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&adapter->dev, + "OV7740: I2C-Adapter doesn't support SMBUS\n"); + return -EIO; + } + + priv = devm_kzalloc(&client->dev, sizeof(struct ov7740_priv), GFP_KERNEL); + if (!priv) { + dev_err(&adapter->dev, + "Failed to allocate memory for private data!\n"); + return -ENOMEM; + } + + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return -EPROBE_DEFER; + + if (!ssdd && !client->dev.of_node) { + dev_err(&adapter->dev, + "OV7740: Missing platform_data for driver\n"); + ret = -EINVAL; + goto err_clk; + } + + if (!ssdd) { + ret = ov7740_probe_dt(client, priv); + if (ret) + goto err_clk; + } + + priv->xvclk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(priv->xvclk)) { + ret = PTR_ERR(priv->xvclk); + goto err_clk; + } + + v4l2_i2c_subdev_init(&priv->subdev, client, &ov7740_subdev_ops); + v4l2_ctrl_handler_init(&priv->hdl, 2); + v4l2_ctrl_new_std(&priv->hdl, &ov7740_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ov7740_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + priv->subdev.ctrl_handler = &priv->hdl; + if (priv->hdl.error) { + ret = priv->hdl.error; + goto err_clk; + } + + ret = ov7740_video_probe(client); + if (ret) + goto err_handler; + + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) + goto err_handler; + + dev_info(&adapter->dev, "OV7740 Probed\n"); + return 0; + +err_handler: + v4l2_ctrl_handler_free(&priv->hdl); +err_clk: + v4l2_clk_put(priv->clk); + return ret; +} + +static int ov7740_remove(struct i2c_client *client) +{ + struct ov7740_priv *priv = to_ov7740(client); + + v4l2_async_unregister_subdev(&priv->subdev); + v4l2_clk_put(priv->clk); + v4l2_device_unregister_subdev(&priv->subdev); + v4l2_ctrl_handler_free(&priv->hdl); + return 0; +} + +static const struct i2c_device_id ov7740_id[] = { + { "ov7740", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov7740_id); + +static const struct of_device_id ov7740_of_match[] = { + {.compatible = "ovti,ov7740", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ov7740_of_match); + +static struct i2c_driver ov7740_i2c_driver = { + .driver = { + .name = "ov7740", + .of_match_table = of_match_ptr(ov7740_of_match), + }, + .probe = ov7740_probe, + .remove = ov7740_remove, + .id_table = ov7740_id, +}; + +module_i2c_driver(ov7740_i2c_driver); + +MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 7740 sensor"); +MODULE_AUTHOR("Josh Wu"); +MODULE_LICENSE("GPL v2"); Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov9640.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov9640.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov9640.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:162 @ static const struct ov9640_reg ov9640_re { OV9640_MTXS, 0x65 }, }; -static enum v4l2_mbus_pixelcode ov9640_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, - V4L2_MBUS_FMT_RGB565_2X8_LE, +static u32 ov9640_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + MEDIA_BUS_FMT_RGB565_2X8_LE, }; /* read a register */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:354 @ static void ov9640_res_roundup(u32 *widt } /* Prepare necessary register changes depending on color encoding */ -static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, +static void ov9640_alter_regs(u32 code, struct ov9640_reg_alt *alt) { switch (code) { default: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: alt->com12 = OV9640_COM12_YUV_AVG; alt->com13 = OV9640_COM13_Y_DELAY_EN | OV9640_COM13_YUV_DLY(0x01); break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_555; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_565; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:379 @ static void ov9640_alter_regs(enum v4l2_ /* Setup registers according to resolution and color encoding */ static int ov9640_write_regs(struct i2c_client *client, u32 width, - enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts) + u32 code, struct ov9640_reg_alt *alts) { const struct ov9640_reg *ov9640_regs, *matrix_regs; int ov9640_regs_len, matrix_regs_len; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:422 @ static int ov9640_write_regs(struct i2c_ } /* select color matrix configuration for given color encoding */ - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_UYVY8_2X8) { matrix_regs = ov9640_regs_yuv; matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); } else { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:490 @ static int ov9640_s_fmt(struct v4l2_subd struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov9640_reg_alt alts = {0}; enum v4l2_colorspace cspace; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; int ret; ov9640_res_roundup(&mf->width, &mf->height); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:503 @ static int ov9640_s_fmt(struct v4l2_subd return ret; switch (code) { - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: cspace = V4L2_COLORSPACE_SRGB; break; default: - code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: + code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_UYVY8_2X8: cspace = V4L2_COLORSPACE_JPEG; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:530 @ static int ov9640_try_fmt(struct v4l2_su mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:544 @ static int ov9640_try_fmt(struct v4l2_su } static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov9640_codes)) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov9740.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/ov9740.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/ov9740.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:13 @ * published by the Free Software Foundation. */ +#include <linux/clk.h> #include <linux/init.h> +#include <linux/delay.h> +#include <linux/gpio.h> #include <linux/module.h> #include <linux/i2c.h> +#include <linux/of_gpio.h> #include <linux/slab.h> #include <linux/v4l2-mediabus.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:194 @ #define OV9740_MAX_WIDTH 1280 #define OV9740_MAX_HEIGHT 720 +#define OV9740_DEFAULT_WIDTH 640 +#define OV9740_DEFAULT_HEIGHT 360 + /* Misc. structures */ struct ov9740_reg { u16 reg; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:207 @ struct ov9740_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; struct v4l2_clk *clk; + struct clk *xvclk; u16 model; u8 revision; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:220 @ struct ov9740_priv { /* For suspend/resume. */ struct v4l2_mbus_framefmt current_mf; bool current_enable; + + struct soc_camera_subdev_desc ssdd_dt; + struct gpio_desc *resetb_gpio; + struct gpio_desc *pwdn_gpio; }; static const struct ov9740_reg ov9740_defaults[] = { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:320 @ static const struct ov9740_reg ov9740_de /* Output Select */ { OV9740_IO_OUTPUT_SEL01, 0x00 }, { OV9740_IO_OUTPUT_SEL02, 0x00 }, - { OV9740_IO_CREL00, 0x00 }, - { OV9740_IO_CREL01, 0x00 }, - { OV9740_IO_CREL02, 0x00 }, + { OV9740_IO_CREL00, 0xe8 }, + { OV9740_IO_CREL01, 0x03 }, + { OV9740_IO_CREL02, 0xff }, /* AWB Control */ { OV9740_AWB_MANUAL_CTRL, 0x00 }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:393 @ static const struct ov9740_reg ov9740_de { OV9740_LN_LENGTH_PCK_HI, 0x06 }, { OV9740_LN_LENGTH_PCK_LO, 0x62 }, - /* MIPI Control */ - { OV9740_MIPI_CTRL00, 0x44 }, /* 0x64 for discontinuous clk */ - { OV9740_MIPI_3837, 0x01 }, - { OV9740_MIPI_CTRL01, 0x0f }, - { OV9740_MIPI_CTRL03, 0x05 }, - { OV9740_MIPI_CTRL05, 0x10 }, - { OV9740_VFIFO_RD_CTRL, 0x16 }, - { OV9740_MIPI_CTRL_3012, 0x70 }, - { OV9740_SC_CMMM_MIPI_CTR, 0x01 }, + { OV9740_ISP_CTRL00, 0xff}, + { OV9740_ISP_CTRL01, 0xef}, + { OV9740_ISP_CTRL03, 0xff}, +}; - /* YUYV order */ - { OV9740_ISP_CTRL19, 0x02 }, +static const struct ov9740_reg ov9740_hvgaw_setting[] = { + /* Binning Enable */ + {0x381a, 0x44}, + + /* Resolution */ + /* X/Y_ADDR_START is empty */ + { OV9740_Y_ADDR_END_HI, 0x02}, + { OV9740_Y_ADDR_END_LO, 0xd3}, + { OV9740_X_OUTPUT_SIZE_HI, 0x02}, + { OV9740_X_OUTPUT_SIZE_LO, 0x80}, + { OV9740_Y_OUTPUT_SIZE_HI, 0x01}, + { OV9740_Y_OUTPUT_SIZE_LO, 0x68}, + + {OV9740_MODE_SELECT, 0x01}, }; -static enum v4l2_mbus_pixelcode ov9740_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, +static const struct ov9740_reg ov9740_sxga_setting[] = { + /* X/Y_ADDR_START is empty */ + {OV9740_Y_ADDR_END_LO, 0xd1}, + {OV9740_X_OUTPUT_SIZE_HI, 0x05}, + {OV9740_X_OUTPUT_SIZE_LO, 0x00}, + {OV9740_Y_OUTPUT_SIZE_HI, 0x02}, + {OV9740_Y_OUTPUT_SIZE_LO, 0xd0}, + + {OV9740_MODE_SELECT, 0x01}, +}; + +static u32 ov9740_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, }; /* read a register */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:583 @ static void ov9740_res_roundup(u32 *widt *width = ALIGN(*width, 4); /* Max resolution is 1280x720 (720p). */ - if (*width > OV9740_MAX_WIDTH) + if (*width <= OV9740_DEFAULT_WIDTH) { + *width = OV9740_DEFAULT_WIDTH; + *height = OV9740_DEFAULT_HEIGHT; + } else { *width = OV9740_MAX_WIDTH; - - if (*height > OV9740_MAX_HEIGHT) *height = OV9740_MAX_HEIGHT; -} - -/* Setup registers according to resolution and color encoding */ -static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height) -{ - u32 x_start; - u32 y_start; - u32 x_end; - u32 y_end; - bool scaling = false; - u32 scale_input_x; - u32 scale_input_y; - int ret; - - if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT)) - scaling = true; - - /* - * Try to use as much of the sensor area as possible when supporting - * smaller resolutions. Depending on the aspect ratio of the - * chosen resolution, we can either use the full width of the sensor, - * or the full height of the sensor (or both if the aspect ratio is - * the same as 1280x720. - */ - if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) { - scale_input_x = (OV9740_MAX_HEIGHT * width) / height; - scale_input_y = OV9740_MAX_HEIGHT; - } else { - scale_input_x = OV9740_MAX_WIDTH; - scale_input_y = (OV9740_MAX_WIDTH * height) / width; } - - /* These describe the area of the sensor to use. */ - x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2; - y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2; - x_end = x_start + scale_input_x - 1; - y_end = y_start + scale_input_y - 1; - - ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff); - if (ret) - goto done; - - ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff); - if (ret) - goto done; - - ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff); - if (ret) - goto done; - - ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff); - if (ret) - goto done; - - ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI, - (scale_input_x - width) >> 8); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO, - (scale_input_x - width) & 0xff); - if (ret) - goto done; - - ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef | - (scaling << 4)); - if (ret) - goto done; - ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff); - -done: - return ret; } /* set the format we will capture in */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:599 @ static int ov9740_s_fmt(struct v4l2_subd struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov9740_priv *priv = to_ov9740(sd); enum v4l2_colorspace cspace; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; int ret; ov9740_res_roundup(&mf->width, &mf->height); switch (code) { - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cspace = V4L2_COLORSPACE_SRGB; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:617 @ static int ov9740_s_fmt(struct v4l2_subd if (ret < 0) return ret; - ret = ov9740_set_res(client, mf->width, mf->height); + /* Set Registers by Resolution */ + if (mf->width == OV9740_MAX_WIDTH && mf->height == OV9740_MAX_HEIGHT) + ret = ov9740_reg_write_array(client, ov9740_sxga_setting, + ARRAY_SIZE(ov9740_sxga_setting)); + else + ret = ov9740_reg_write_array(client, ov9740_hvgaw_setting, + ARRAY_SIZE(ov9740_hvgaw_setting)); if (ret < 0) return ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:641 @ static int ov9740_try_fmt(struct v4l2_su ov9740_res_roundup(&mf->width, &mf->height); mf->field = V4L2_FIELD_NONE; - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; + mf->colorspace = V4L2_COLORSPACE_SRGB; + + return 0; +} + +static int ov9740_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + static int first_time = 1; + + mf->code = ov9740_codes[0]; mf->colorspace = V4L2_COLORSPACE_SRGB; + mf->field = V4L2_FIELD_NONE; + + if (first_time) { + /* Initial setting is 640x360 */ + mf->width = OV9740_DEFAULT_WIDTH; + mf->height = OV9740_DEFAULT_HEIGHT; + first_time = 0; + } else { + ov9740_res_roundup(&mf->width, &mf->height); + } return 0; } + static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov9740_codes)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:733 @ static int ov9740_s_power(struct v4l2_su int ret; if (on) { + clk_prepare_enable(priv->xvclk); + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); if (ret < 0) return ret; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:750 @ static int ov9740_s_power(struct v4l2_su } soc_camera_power_off(&client->dev, ssdd, priv->clk); + + clk_disable_unprepare(priv->xvclk); } return 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:862 @ static int ov9740_g_mbus_config(struct v static struct v4l2_subdev_video_ops ov9740_video_ops = { .s_stream = ov9740_s_stream, .s_mbus_fmt = ov9740_s_fmt, + .g_mbus_fmt = ov9740_g_fmt, .try_mbus_fmt = ov9740_try_fmt, .enum_mbus_fmt = ov9740_enum_fmt, .cropcap = ov9740_cropcap, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:887 @ static const struct v4l2_ctrl_ops ov9740 .s_ctrl = ov9740_s_ctrl, }; +/* OF probe functions */ +static int ov9740_hw_power(struct device *dev, int on) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov9740_priv *priv = to_ov9740(sd); + + dev_dbg(&client->dev, "%s: %s the camera\n", + __func__, on ? "ENABLE" : "DISABLE"); + + if (priv->pwdn_gpio) + gpiod_direction_output(priv->pwdn_gpio, !on); + + /* We need wait for ~1ms, then access the SCCB */ + if (on) + usleep_range(1000, 2000); + + return 0; +} + +static int ov9740_hw_reset(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov9740_priv *priv = to_ov9740(sd); + + if (priv->resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv->resetb_gpio, 1); + usleep_range(1000, 3000); + gpiod_direction_output(priv->resetb_gpio, 0); + } + + usleep_range(1000, 2000); + + return 0; +} + +static int ov9740_probe_dt(struct i2c_client *client, + struct ov9740_priv *priv) +{ + /* Request the reset GPIO deasserted */ + priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", + GPIOD_OUT_LOW); + if (!priv->resetb_gpio) + dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); + else if (IS_ERR(priv->resetb_gpio)) + return PTR_ERR(priv->resetb_gpio); + + /* Request the power down GPIO asserted */ + priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + if (!priv->pwdn_gpio) + dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); + else if (IS_ERR(priv->pwdn_gpio)) + return PTR_ERR(priv->pwdn_gpio); + + /* Initialize the soc_camera_subdev_desc */ + priv->ssdd_dt.power = ov9740_hw_power; + priv->ssdd_dt.reset = ov9740_hw_reset; + client->dev.platform_data = &priv->ssdd_dt; + + return 0; +} + /* * i2c_driver function */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:962 @ static int ov9740_probe(struct i2c_clien struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!ssdd) { - dev_err(&client->dev, "Missing platform_data for driver\n"); - return -EINVAL; - } - priv = devm_kzalloc(&client->dev, sizeof(struct ov9740_priv), GFP_KERNEL); if (!priv) { dev_err(&client->dev, "Failed to allocate private data!\n"); return -ENOMEM; } + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + return -EPROBE_DEFER; + } + + if (!ssdd && !client->dev.of_node) { + dev_err(&client->dev, "Missing platform_data for driver\n"); + ret = -EINVAL; + goto err_clk; + } + + if (!ssdd) { + ret = ov9740_probe_dt(client, priv); + if (ret) + goto err_clk; + } + + priv->xvclk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(priv->xvclk)) { + ret = PTR_ERR(priv->xvclk); + goto err_clk; + } + v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops); v4l2_ctrl_handler_init(&priv->hdl, 13); v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); + V4L2_CID_HFLIP, 0, 1, 1, 1); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) - return priv->hdl.error; - - priv->clk = v4l2_clk_get(&client->dev, "mclk"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto eclkget; + if (priv->hdl.error) { + ret = priv->hdl.error; + goto err_clk; } ret = ov9740_video_probe(client); - if (ret < 0) { - v4l2_clk_put(priv->clk); -eclkget: - v4l2_ctrl_handler_free(&priv->hdl); - } + if (ret < 0) + goto err_handler; + + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) + goto err_handler; + + return 0; + +err_handler: + v4l2_ctrl_handler_free(&priv->hdl); +err_clk: + v4l2_clk_put(priv->clk); return ret; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1025 @ static int ov9740_remove(struct i2c_clie { struct ov9740_priv *priv = i2c_get_clientdata(client); + v4l2_async_unregister_subdev(&priv->subdev); v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1038 @ static const struct i2c_device_id ov9740 }; MODULE_DEVICE_TABLE(i2c, ov9740_id); +static const struct of_device_id ov9740_of_match[] = { + {.compatible = "ovti,ov9740", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ov9740_of_match); + static struct i2c_driver ov9740_i2c_driver = { .driver = { .name = "ov9740", + .of_match_table = of_match_ptr(ov9740_of_match), }, .probe = ov9740_probe, .remove = ov9740_remove, Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/rj54n1cb0c.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/rj54n1cb0c.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:114 @ /* RJ54N1CB0C has only one fixed colorspace per pixelcode */ struct rj54n1_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct rj54n1_datafmt *rj54n1_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt, + u32 code, const struct rj54n1_datafmt *fmt, int n) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:132 @ static const struct rj54n1_datafmt *rj54 } static const struct rj54n1_datafmt rj54n1_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, }; struct rj54n1_clock_div { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:489 @ static int reg_write_multiple(struct i2c } static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(rj54n1_colour_fmts)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:968 @ static int rj54n1_try_fmt(struct v4l2_su struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); const struct rj54n1_datafmt *fmt; - int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE; + int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE; dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", __func__, mf->code, mf->width, mf->height); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1028 @ static int rj54n1_s_fmt(struct v4l2_subd /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ switch (mf->code) { - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: ret = reg_write(client, RJ54N1_OUT_SEL, 0); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: ret = reg_write(client, RJ54N1_OUT_SEL, 0); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); break; - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: ret = reg_write(client, RJ54N1_OUT_SEL, 5); break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1086 @ static int rj54n1_s_fmt(struct v4l2_subd /* Special case: a raw mode with 10 bits of data per clock tick */ if (!ret) ret = reg_set(client, RJ54N1_OCLK_SEL_EN, - (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2); + (mf->code == MEDIA_BUS_FMT_SBGGR10_1X10) << 1, 2); if (ret < 0) return ret; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/tw9910.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/soc_camera/tw9910.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/soc_camera/tw9910.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:708 @ static int tw9910_g_fmt(struct v4l2_subd mf->width = priv->scale->width; mf->height = priv->scale->height; - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; mf->field = V4L2_FIELD_INTERLACED_BT; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:727 @ static int tw9910_s_fmt(struct v4l2_subd /* * check color format */ - if (mf->code != V4L2_MBUS_FMT_UYVY8_2X8) + if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8) return -EINVAL; mf->colorspace = V4L2_COLORSPACE_JPEG; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:754 @ static int tw9910_try_fmt(struct v4l2_su return -EINVAL; } - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:825 @ static struct v4l2_subdev_core_ops tw991 }; static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/sr030pc30.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/sr030pc30.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/sr030pc30.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:168 @ struct sr030pc30_info { }; struct sr030pc30_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 ispctl1_reg; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:204 @ static const struct sr030pc30_frmsize sr /* supported pixel formats */ static const struct sr030pc30_format sr030pc30_formats[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x03, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x02, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x01, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x40, }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:475 @ static int sr030pc30_s_ctrl(struct v4l2_ } static int sr030pc30_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (!code || index >= ARRAY_SIZE(sr030pc30_formats)) return -EINVAL; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp514x.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/tvp514x.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp514x.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:759 @ static int tvp514x_s_ctrl(struct v4l2_ct */ static int tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV10_2X10; + *code = MEDIA_BUS_FMT_YUYV10_2X10; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:787 @ tvp514x_mbus_fmt(struct v4l2_subdev *sd, /* Calculate height and width based on current standard */ current_std = decoder->current_std; - f->code = V4L2_MBUS_FMT_YUYV8_2X8; + f->code = MEDIA_BUS_FMT_YUYV8_2X8; f->width = decoder->std_list[current_std].width; f->height = decoder->std_list[current_std].height; f->field = V4L2_FIELD_INTERLACED; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:945 @ static int tvp514x_enum_mbus_code(struct if (index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_YUYV8_2X8; + code->code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:970 @ static int tvp514x_get_pad_format(struct return 0; } - format->format.code = V4L2_MBUS_FMT_YUYV8_2X8; + format->format.code = MEDIA_BUS_FMT_YUYV8_2X8; format->format.width = tvp514x_std_list[decoder->current_std].width; format->format.height = tvp514x_std_list[decoder->current_std].height; format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:994 @ static int tvp514x_set_pad_format(struct struct tvp514x_decoder *decoder = to_decoder(sd); if (fmt->format.field != V4L2_FIELD_INTERLACED || - fmt->format.code != V4L2_MBUS_FMT_YUYV8_2X8 || + fmt->format.code != MEDIA_BUS_FMT_YUYV8_2X8 || fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M || fmt->format.width != tvp514x_std_list[decoder->current_std].width || fmt->format.height != tvp514x_std_list[decoder->current_std].height) Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp5150.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/tvp5150.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp5150.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:821 @ static v4l2_std_id tvp5150_read_std(stru } static int tvp5150_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:843 @ static int tvp5150_mbus_fmt(struct v4l2_ f->width = decoder->rect.width; f->height = decoder->rect.height; - f->code = V4L2_MBUS_FMT_UYVY8_2X8; + f->code = MEDIA_BUS_FMT_UYVY8_2X8; f->field = V4L2_FIELD_SEQ_TB; f->colorspace = V4L2_COLORSPACE_SMPTE170M; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp7002.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/tvp7002.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/tvp7002.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:629 @ static int tvp7002_mbus_fmt(struct v4l2_ f->width = bt->width; f->height = bt->height; - f->code = V4L2_MBUS_FMT_YUYV10_1X20; + f->code = MEDIA_BUS_FMT_YUYV10_1X20; f->field = device->current_timings->scanmode; f->colorspace = device->current_timings->color_space; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:759 @ static int tvp7002_s_register(struct v4l */ static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { /* Check requested format index is within range */ if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV10_1X20; + *code = MEDIA_BUS_FMT_YUYV10_1X20; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:862 @ tvp7002_enum_mbus_code(struct v4l2_subde if (code->index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_YUYV10_1X20; + code->code = MEDIA_BUS_FMT_YUYV10_1X20; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:881 @ tvp7002_get_pad_format(struct v4l2_subde { struct tvp7002 *tvp7002 = to_tvp7002(sd); - fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20; + fmt->format.code = MEDIA_BUS_FMT_YUYV10_1X20; fmt->format.width = tvp7002->current_timings->timings.bt.width; fmt->format.height = tvp7002->current_timings->timings.bt.height; fmt->format.field = tvp7002->current_timings->scanmode; Index: linux-3.18.13-rt10-r7s4/drivers/media/i2c/vs6624.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/i2c/vs6624.c +++ linux-3.18.13-rt10-r7s4/drivers/media/i2c/vs6624.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:48 @ struct vs6624 { }; static const struct vs6624_format { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; enum v4l2_colorspace colorspace; } vs6624_formats[] = { { - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, }, { - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, }, { - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, }, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:68 @ static const struct vs6624_format { static struct v4l2_mbus_framefmt vs6624_default_fmt = { .width = VGA_WIDTH, .height = VGA_HEIGHT, - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:561 @ static int vs6624_s_ctrl(struct v4l2_ctr } static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(vs6624_formats)) return -EINVAL; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:608 @ static int vs6624_s_mbus_fmt(struct v4l2 /* set image format */ switch (fmt->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: vs6624_write(sd, VS6624_IMG_FMT0, 0x0); vs6624_write(sd, VS6624_YUV_SETUP, 0x1); break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: vs6624_write(sd, VS6624_IMG_FMT0, 0x0); vs6624_write(sd, VS6624_YUV_SETUP, 0x3); break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: vs6624_write(sd, VS6624_IMG_FMT0, 0x4); vs6624_write(sd, VS6624_RGB_SETUP, 0x0); break; Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-av-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/cx18/cx18-av-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-av-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:955 @ static int cx18_av_s_mbus_fmt(struct v4l int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-controls.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/cx18/cx18-controls.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-controls.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:101 @ static int cx18_s_video_encoding(struct /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt); return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-ioctl.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/cx18/cx18-ioctl.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/cx18/cx18-ioctl.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:297 @ static int cx18_s_fmt_vid_cap(struct fil mbus_fmt.width = cx->cxhdl.width = w; mbus_fmt.height = cx->cxhdl.height = h; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/cx23885/cx23885-video.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/cx23885/cx23885-video.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/cx23885/cx23885-video.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:611 @ static int vidioc_s_fmt_vid_cap(struct f dev->field = f->fmt.pix.field; dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, dev->width, dev->height, dev->field); - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); /* s_mbus_fmt overwrites f->fmt.pix.field, restore it */ Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/ivtv/ivtv-controls.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/ivtv/ivtv-controls.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/ivtv/ivtv-controls.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:72 @ static int ivtv_s_video_encoding(struct /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/ivtv/ivtv-ioctl.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/ivtv/ivtv-ioctl.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/ivtv/ivtv-ioctl.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:598 @ static int ivtv_s_fmt_vid_cap(struct fil fmt->fmt.pix.width /= 2; mbus_fmt.width = fmt->fmt.pix.width; mbus_fmt.height = h; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); return ivtv_g_fmt_vid_cap(file, fh, fmt); } Index: linux-3.18.13-rt10-r7s4/drivers/media/pci/saa7134/saa7134-empress.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/pci/saa7134/saa7134-empress.c +++ linux-3.18.13-rt10-r7s4/drivers/media/pci/saa7134/saa7134-empress.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:143 @ static int empress_s_fmt_vid_cap(struct struct saa7134_dev *dev = video_drvdata(file); struct v4l2_mbus_framefmt mbus_fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:160 @ static int empress_try_fmt_vid_cap(struc struct saa7134_dev *dev = video_drvdata(file); struct v4l2_mbus_framefmt mbus_fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/blackfin/bfin_capture.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/blackfin/bfin_capture.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/blackfin/bfin_capture.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:52 @ struct bcap_format { char *desc; u32 pixelformat; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; int bpp; /* bits per pixel */ int dlen; /* data length for ppi in bits */ }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:119 @ static const struct bcap_format bcap_for { .desc = "YCbCr 4:2:2 Interleaved UYVY", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .bpp = 16, .dlen = 8, }, { .desc = "YCbCr 4:2:2 Interleaved YUYV", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 16, .dlen = 8, }, { .desc = "YCbCr 4:2:2 Interleaved UYVY", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16, + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .dlen = 16, }, { .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .bpp = 16, .dlen = 8, }, { .desc = "RGB 444", .pixelformat = V4L2_PIX_FMT_RGB444, - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 16, .dlen = 8, }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:164 @ static struct bcap_buffer *to_bcap_vb(st static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) { - enum v4l2_mbus_pixelcode code; + u32 code; struct bcap_format *sf; unsigned int num_formats = 0; int i, j; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/davinci/vpbe.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/davinci/vpbe.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/davinci/vpbe.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:230 @ static int vpbe_set_output(struct vpbe_d vpbe_current_encoder_info(vpbe_dev); struct vpbe_config *cfg = vpbe_dev->cfg; struct venc_platform_data *venc_device = vpbe_dev->venc_device; - enum v4l2_mbus_pixelcode if_params; + u32 if_params; int enc_out_index; int sd_index; int ret = 0; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/davinci/vpfe_capture.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/davinci/vpfe_capture.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/davinci/vpfe_capture.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:417 @ static int vpfe_config_image_format(stru /* assume V4L2_PIX_FMT_UYVY as default */ pix->pixelformat = V4L2_PIX_FMT_UYVY; v4l2_fill_mbus_format(&mbus_fmt, pix, - V4L2_MBUS_FMT_YUYV10_2X10); + MEDIA_BUS_FMT_YUYV10_2X10); } else { pix->field = V4L2_FIELD_NONE; /* assume V4L2_PIX_FMT_SBGGR8 */ pix->pixelformat = V4L2_PIX_FMT_SBGGR8; v4l2_fill_mbus_format(&mbus_fmt, pix, - V4L2_MBUS_FMT_SBGGR8_1X8); + MEDIA_BUS_FMT_SBGGR8_1X8); } /* if sub device supports g_mbus_fmt, override the defaults */ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-capture.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-capture.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-capture.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:752 @ static int fimc_cap_enum_fmt_mplane(stru return -EINVAL; strncpy(f->description, fmt->name, sizeof(f->description) - 1); f->pixelformat = fmt->fourcc; - if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8) + if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) f->flags |= V4L2_FMT_FLAG_COMPRESSED; return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:84 @ static struct fimc_fmt fimc_formats[] = .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, }, { .name = "YUV 4:4:4", - .mbus_code = V4L2_MBUS_FMT_YUV10_1X30, + .mbus_code = MEDIA_BUS_FMT_YUV10_1X30, .flags = FMT_FLAGS_WRITEBACK, }, { .name = "YUV 4:2:2 packed, YCbYCr", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:93 @ static struct fimc_fmt fimc_formats[] = .color = FIMC_FMT_YCBYCR422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, CbYCrY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:102 @ static struct fimc_fmt fimc_formats[] = .color = FIMC_FMT_CBYCRY422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, CrYCbY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:111 @ static struct fimc_fmt fimc_formats[] = .color = FIMC_FMT_CRYCBY422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, YCrYCb", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:120 @ static struct fimc_fmt fimc_formats[] = .color = FIMC_FMT_YCRYCB422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 planar, Y/Cb/Cr", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:193 @ static struct fimc_fmt fimc_formats[] = .depth = { 8 }, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_JPEG_1X8, + .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED, }, { .name = "S5C73MX interleaved UYVY/JPEG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:203 @ static struct fimc_fmt fimc_formats[] = .memplanes = 2, .colplanes = 1, .mdataplanes = 0x2, /* plane 1 holds frame meta data */ - .mbus_code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, + .mbus_code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED, }, }; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-core.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-core.h +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-core.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:582 @ static inline bool fimc_jpeg_fourcc(u32 static inline bool fimc_user_defined_mbus_fmt(u32 code) { - return (code == V4L2_MBUS_FMT_JPEG_1X8 || - code == V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8); + return (code == MEDIA_BUS_FMT_JPEG_1X8 || + code == MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8); } /* Return the alpha component bit mask */ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-isp.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-isp.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-isp.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:44 @ static const struct fimc_fmt fimc_isp_fo .depth = { 8 }, .color = FIMC_FMT_RAW8, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, }, { .name = "RAW10 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG10, .depth = { 10 }, .color = FIMC_FMT_RAW10, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, }, { .name = "RAW12 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG12, .depth = { 12 }, .color = FIMC_FMT_RAW12, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, }, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:152 @ static int fimc_isp_subdev_get_fmt(struc if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) { mf->colorspace = V4L2_COLORSPACE_JPEG; - mf->code = V4L2_MBUS_FMT_YUV10_1X30; + mf->code = MEDIA_BUS_FMT_YUV10_1X30; } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:178 @ static void __isp_subdev_try_format(stru FIMC_ISP_SINK_WIDTH_MAX, 0, &mf->height, FIMC_ISP_SINK_HEIGHT_MIN, FIMC_ISP_SINK_HEIGHT_MAX, 0, 0); - mf->code = V4L2_MBUS_FMT_SGRBG10_1X10; + mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; } else { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) format = v4l2_subdev_get_try_format(fh, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:191 @ static void __isp_subdev_try_format(stru mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT; if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) { - mf->code = V4L2_MBUS_FMT_YUV10_1X30; + mf->code = MEDIA_BUS_FMT_YUV10_1X30; mf->colorspace = V4L2_COLORSPACE_JPEG; } else { mf->code = format->code; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:683 @ static void __isp_subdev_set_default_for FIMC_ISP_CAC_MARGIN_WIDTH; isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT; - isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10; + isp->sink_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10; isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; - isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10; + isp->src_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10; __is_set_frame_size(is, &isp->src_fmt); } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-lite.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-lite.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-lite.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:51 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_YCBYCR422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, CbYCrY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_CBYCRY422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, CrYCbY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:69 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_CRYCBY422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, YCrYCb", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_YCRYCB422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "RAW8 (GRBG)", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:87 @ static const struct fimc_fmt fimc_lite_f .depth = { 8 }, .color = FIMC_FMT_RAW8, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, .flags = FMT_FLAGS_RAW_BAYER, }, { .name = "RAW10 (GRBG)", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:96 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_RAW10, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, .flags = FMT_FLAGS_RAW_BAYER, }, { .name = "RAW12 (GRBG)", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:105 @ static const struct fimc_fmt fimc_lite_f .depth = { 16 }, .color = FIMC_FMT_RAW12, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, .flags = FMT_FLAGS_RAW_BAYER, }, }; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-lite-reg.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-lite-reg.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-lite-reg.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:115 @ void flite_hw_set_test_pattern(struct fi } static const u32 src_pixfmt_map[8][3] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR, + { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB, + { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY, + { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY, + { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 }, - { V4L2_MBUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 }, - { V4L2_MBUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 }, - { V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 }, + { MEDIA_BUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) }, }; /* Set camera input pixel format and resolution */ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) { - enum v4l2_mbus_pixelcode pixelcode = f->fmt->mbus_code; + u32 pixelcode = f->fmt->mbus_code; int i = ARRAY_SIZE(src_pixfmt_map); u32 cfg; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:235 @ static void flite_hw_set_pack12(struct f static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) { static const u32 pixcode[4][2] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, - { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB }, - { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY }, - { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY }, + { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, + { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB }, + { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY }, + { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY }, }; u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT); int i = ARRAY_SIZE(pixcode); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-reg.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/fimc-reg.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/fimc-reg.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:595 @ struct mbus_pixfmt_desc { }; static const struct mbus_pixfmt_desc pix_desc[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 }, - { V4L2_MBUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 }, - { V4L2_MBUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 }, - { V4L2_MBUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 }, + { MEDIA_BUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 }, + { MEDIA_BUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 }, + { MEDIA_BUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 }, + { MEDIA_BUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 }, }; int fimc_hw_set_camera_source(struct fimc_dev *fimc, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:692 @ int fimc_hw_set_camera_type(struct fimc_ /* TODO: add remaining supported formats. */ switch (vid_cap->ci_fmt.code) { - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT; break; - case V4L2_MBUS_FMT_JPEG_1X8: - case V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8: + case MEDIA_BUS_FMT_JPEG_1X8: + case MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8: tmp = FIMC_REG_CSIIMGFMT_USER(1); cfg |= FIMC_REG_CIGCTRL_CAM_JPEG; break; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/mipi-csis.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos4-is/mipi-csis.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos4-is/mipi-csis.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:241 @ struct csis_state { */ struct csis_pix_format { unsigned int pix_width_alignment; - enum v4l2_mbus_pixelcode code; + u32 code; u32 fmt_reg; u8 data_alignment; }; static const struct csis_pix_format s5pcsis_formats[] = { { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT, .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .fmt_reg = S5PCSIS_CFG_FMT_USER(1), .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, + .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .fmt_reg = S5PCSIS_CFG_FMT_USER(1), .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_SGRBG8_1X8, + .code = MEDIA_BUS_FMT_SGRBG8_1X8, .fmt_reg = S5PCSIS_CFG_FMT_RAW8, .data_alignment = 24, }, { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .fmt_reg = S5PCSIS_CFG_FMT_RAW10, .data_alignment = 24, }, { - .code = V4L2_MBUS_FMT_SGRBG12_1X12, + .code = MEDIA_BUS_FMT_SGRBG12_1X12, .fmt_reg = S5PCSIS_CFG_FMT_RAW12, .data_alignment = 24, } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos-gsc/gsc-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos-gsc/gsc-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos-gsc/gsc-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:57 @ static const struct gsc_fmt gsc_formats[ .corder = GSC_CBCR, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, }, { .name = "YUV 4:2:2 packed, CbYCrY", .pixelformat = V4L2_PIX_FMT_UYVY, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:67 @ static const struct gsc_fmt gsc_formats[ .corder = GSC_CBCR, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, }, { .name = "YUV 4:2:2 packed, CrYCbY", .pixelformat = V4L2_PIX_FMT_VYUY, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:77 @ static const struct gsc_fmt gsc_formats[ .corder = GSC_CRCB, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, }, { .name = "YUV 4:2:2 packed, YCrYCb", .pixelformat = V4L2_PIX_FMT_YVYU, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:87 @ static const struct gsc_fmt gsc_formats[ .corder = GSC_CRCB, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, }, { .name = "YUV 4:4:4 planar, YCbYCr", .pixelformat = V4L2_PIX_FMT_YUV32, Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos-gsc/gsc-core.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/exynos-gsc/gsc-core.h +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/exynos-gsc/gsc-core.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:120 @ enum gsc_yuv_fmt { * @flags: flags indicating which operation mode format applies to */ struct gsc_fmt { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; char *name; u32 pixelformat; u32 color; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/marvell-ccic/mcam-core.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/marvell-ccic/mcam-core.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/marvell-ccic/mcam-core.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:109 @ static struct mcam_format_struct { __u32 pixelformat; int bpp; /* Bytes per pixel */ bool planar; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; } mcam_formats[] = { { .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { .desc = "UYVY 4:2:2", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { .desc = "YUV 4:2:2 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV422P, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "YUV 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV420, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "YVU 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YVU420, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "RGB 444", .pixelformat = V4L2_PIX_FMT_RGB444, - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 2, .planar = false, }, { .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .bpp = 2, .planar = false, }, { .desc = "Raw RGB Bayer", .pixelformat = V4L2_PIX_FMT_SBGGR8, - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 1, .planar = false, }, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:193 @ static const struct v4l2_pix_format mcam .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, }; -static const enum v4l2_mbus_pixelcode mcam_def_mbus_code = - V4L2_MBUS_FMT_YUYV8_2X8; +static const u32 mcam_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; /* Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/marvell-ccic/mcam-core.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/marvell-ccic/mcam-core.h +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/marvell-ccic/mcam-core.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:186 @ struct mcam_camera { /* Current operating parameters */ struct v4l2_pix_format pix_format; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; /* Locks */ struct mutex s_mutex; /* Access to this structure */ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispccdc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispccdc.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispccdc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:39 @ __ccdc_get_format(struct isp_ccdc_device unsigned int pad, enum v4l2_subdev_format_whence which); static const unsigned int ccdc_fmts[] = { - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_SRGGB12_1X12, - V4L2_MBUS_FMT_SBGGR12_1X12, - V4L2_MBUS_FMT_SGBRG12_1X12, - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y12_1X12, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:269 @ static int __ccdc_lsc_enable(struct isp_ __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE); - if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) && - (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) && - (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) && - (format->code != V4L2_MBUS_FMT_SGBRG10_1X10)) + if ((format->code != MEDIA_BUS_FMT_SGRBG10_1X10) && + (format->code != MEDIA_BUS_FMT_SRGGB10_1X10) && + (format->code != MEDIA_BUS_FMT_SBGGR10_1X10) && + (format->code != MEDIA_BUS_FMT_SGBRG10_1X10)) return -EINVAL; if (enable) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:974 @ static void ccdc_config_sync_if(struct i format = &ccdc->formats[CCDC_PAD_SINK]; - if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 || - format->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || + format->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* According to the OMAP3 TRM the input mode only affects SYNC * mode, enabling BT.656 mode should take precedence. However, * in practice setting the input mode to YCbCr data on 8 bits @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1023 @ static void ccdc_config_sync_if(struct i /* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The * hardware seems to ignore it in all other input modes. */ - if (format->code == V4L2_MBUS_FMT_UYVY8_2X8) + if (format->code == MEDIA_BUS_FMT_UYVY8_2X8) isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_Y8POS); else @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1171 @ static void ccdc_configure(struct isp_cc if (ccdc->bt656) bridge = ISPCTRL_PAR_BRIDGE_DISABLE; - else if (fmt_info->code == V4L2_MBUS_FMT_YUYV8_2X8) + else if (fmt_info->code == MEDIA_BUS_FMT_YUYV8_2X8) bridge = ISPCTRL_PAR_BRIDGE_LENDIAN; - else if (fmt_info->code == V4L2_MBUS_FMT_UYVY8_2X8) + else if (fmt_info->code == MEDIA_BUS_FMT_UYVY8_2X8) bridge = ISPCTRL_PAR_BRIDGE_BENDIAN; else bridge = ISPCTRL_PAR_BRIDGE_DISABLE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1202 @ static void ccdc_configure(struct isp_cc /* Mosaic filter */ switch (format->code) { - case V4L2_MBUS_FMT_SRGGB10_1X10: - case V4L2_MBUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SRGGB12_1X12: ccdc_pattern = ccdc_srggb_pattern; break; - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR12_1X12: ccdc_pattern = ccdc_sbggr_pattern; break; - case V4L2_MBUS_FMT_SGBRG10_1X10: - case V4L2_MBUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGBRG12_1X12: ccdc_pattern = ccdc_sgbrg_pattern; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1270 @ static void ccdc_configure(struct isp_cc /* The CCDC outputs data in UYVY order by default. Swap bytes to get * YUYV. */ - if (format->code == V4L2_MBUS_FMT_YUYV8_1X16) + if (format->code == MEDIA_BUS_FMT_YUYV8_1X16) isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_BSWD); else @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1970 @ ccdc_try_format(struct isp_ccdc_device * enum v4l2_subdev_format_whence which) { const struct isp_format_info *info; - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; unsigned int width = fmt->width; unsigned int height = fmt->height; struct v4l2_rect *crop; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1986 @ ccdc_try_format(struct isp_ccdc_device * /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(ccdc_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; /* Clamp the input size. */ fmt->width = clamp_t(u32, width, 32, 4096); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2010 @ ccdc_try_format(struct isp_ccdc_device * * configured to pack bytes in BT.656, hiding the inaccuracy. * In all cases bytes can be swapped. */ - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 || - fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* Use the user requested format if YUV. */ - if (pixelcode == V4L2_MBUS_FMT_YUYV8_2X8 || - pixelcode == V4L2_MBUS_FMT_UYVY8_2X8 || - pixelcode == V4L2_MBUS_FMT_YUYV8_1X16 || - pixelcode == V4L2_MBUS_FMT_UYVY8_1X16) + if (pixelcode == MEDIA_BUS_FMT_YUYV8_2X8 || + pixelcode == MEDIA_BUS_FMT_UYVY8_2X8 || + pixelcode == MEDIA_BUS_FMT_YUYV8_1X16 || + pixelcode == MEDIA_BUS_FMT_UYVY8_1X16) fmt->code = pixelcode; - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; - else if (fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) - fmt->code = V4L2_MBUS_FMT_UYVY8_1X16; + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8) + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; + else if (fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) + fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; } /* Hardcode the output size to the crop rectangle size. */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2050 @ ccdc_try_format(struct isp_ccdc_device * fmt->code = info->truncated; /* YUV formats are not supported by the video port. */ - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 || - fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) fmt->code = 0; /* The number of lines that can be clocked out from the video @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2086 @ static void ccdc_try_crop(struct isp_ccd * to keep the Bayer pattern. */ info = omap3isp_video_format_info(sink->code); - if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) { + if (info->flavor != MEDIA_BUS_FMT_Y8_1X8) { crop->left &= ~1; crop->top &= ~1; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2106 @ static void ccdc_try_crop(struct isp_ccd sink->height - crop->top); /* Odd width/height values don't make sense for Bayer formats. */ - if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) { + if (info->flavor != MEDIA_BUS_FMT_Y8_1X8) { crop->width &= ~1; crop->height &= ~1; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2138 @ static int ccdc_enum_mbus_code(struct v4 format = __ccdc_get_format(ccdc, fh, code->pad, V4L2_SUBDEV_FORMAT_TRY); - if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 || - format->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || + format->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* In YUV mode the CCDC can swap bytes. */ if (code->index == 0) - code->code = V4L2_MBUS_FMT_YUYV8_1X16; + code->code = MEDIA_BUS_FMT_YUYV8_1X16; else if (code->index == 1) - code->code = V4L2_MBUS_FMT_UYVY8_1X16; + code->code = MEDIA_BUS_FMT_UYVY8_1X16; else return -EINVAL; } else { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2386 @ static int ccdc_set_format(struct v4l2_s * return true if the combination is possible * return false otherwise */ -static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in, - enum v4l2_mbus_pixelcode out, - unsigned int additional_shift) +static bool ccdc_is_shiftable(u32 in, u32 out, unsigned int additional_shift) { const struct isp_format_info *in_info, *out_info; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2453 @ static int ccdc_init_formats(struct v4l2 memset(&format, 0, sizeof(format)); format.pad = CCDC_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ccdc_set_format(sd, fh, &format); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispccp2.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispccp2.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispccp2.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:292 @ static void ccp2_lcx_config(struct isp_c u32 val, format; switch (config->format) { - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP; break; - case V4L2_MBUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: default: format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */ break; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:441 @ static void ccp2_mem_configure(struct is u32 val, hwords; if (sink_pixcode != source_pixcode && - sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8) + sink_pixcode == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) dpcm_decompress = 1; ccp2_pwr_cfg(ccp2); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:607 @ void omap3isp_ccp2_isr(struct isp_ccp2_d */ static const unsigned int ccp2_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:646 @ static void ccp2_try_format(struct isp_c switch (pad) { case CCP2_PAD_SINK: - if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + if (fmt->code != MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; if (ccp2->input == CCP2_INPUT_SENSOR) { fmt->width = clamp_t(u32, fmt->width, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:674 @ static void ccp2_try_format(struct isp_c */ format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; break; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:811 @ static int ccp2_init_formats(struct v4l2 memset(&format, 0, sizeof(format)); format.pad = CCP2_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ccp2_set_format(sd, fh, &format); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispcsi2.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispcsi2.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispcsi2.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:81 @ static void csi2_recv_config(struct isp_ } static const unsigned int csi2_input_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, - V4L2_MBUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_YUYV8_2X8, }; /* To set the format on the CSI2 requires a mapping function that takes @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:174 @ static u16 csi2_ctx_map_format(struct is int fmtidx, destidx, is_3630; switch (fmt->code) { - case V4L2_MBUS_FMT_SGRBG10_1X10: - case V4L2_MBUS_FMT_SRGGB10_1X10: - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: fmtidx = 0; break; - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: - case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: fmtidx = 1; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: fmtidx = 2; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:846 @ csi2_try_format(struct isp_csi2_device * unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_mbus_framefmt *format; const struct isp_format_info *info; unsigned int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:861 @ csi2_try_format(struct isp_csi2_device * /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(csi2_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; fmt->width = clamp_t(u32, fmt->width, 1, 8191); fmt->height = clamp_t(u32, fmt->height, 1, 8191); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1032 @ static int csi2_init_formats(struct v4l2 memset(&format, 0, sizeof(format)); format.pad = CSI2_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; csi2_set_format(sd, fh, &format); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/isppreview.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/isppreview.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/isppreview.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:967 @ static void preview_setup_hw(struct isp_ * @prev: pointer to previewer private structure * @pixelcode: pixel code */ -static void -preview_config_ycpos(struct isp_prev_device *prev, - enum v4l2_mbus_pixelcode pixelcode) +static void preview_config_ycpos(struct isp_prev_device *prev, u32 pixelcode) { struct isp_device *isp = to_isp_device(prev); enum preview_ycpos_mode mode; switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: mode = YCPOS_CrYCbY; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: mode = YCPOS_YCrYCb; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1029 @ static void preview_config_input_format( ISPPRV_PCR_WIDTH); switch (info->flavor) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: prev->params.cfa_order = 0; break; - case V4L2_MBUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: prev->params.cfa_order = 1; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: prev->params.cfa_order = 2; break; - case V4L2_MBUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: prev->params.cfa_order = 3; break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1079 @ static void preview_config_input_size(st unsigned int elv = prev->crop.top + prev->crop.height - 1; u32 features; - if (format->code != V4L2_MBUS_FMT_Y8_1X8 && - format->code != V4L2_MBUS_FMT_Y10_1X10) { + if (format->code != MEDIA_BUS_FMT_Y8_1X8 && + format->code != MEDIA_BUS_FMT_Y10_1X10) { sph -= 2; eph += 2; slv -= 2; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1710 @ __preview_get_crop(struct isp_prev_devic /* previewer format descriptions */ static const unsigned int preview_input_fmts[] = { - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, }; static const unsigned int preview_output_fmts[] = { - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1743 @ static void preview_try_format(struct is struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_rect *crop; unsigned int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1775 @ static void preview_try_format(struct is /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(preview_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; break; case PREV_PAD_SOURCE: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1783 @ static void preview_try_format(struct is *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which); switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: fmt->code = pixelcode; break; default: - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; break; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1844 @ static void preview_try_crop(struct isp_ * and no columns in other modes. Increase the margins based on the sink * format. */ - if (sink->code != V4L2_MBUS_FMT_Y8_1X8 && - sink->code != V4L2_MBUS_FMT_Y10_1X10) { + if (sink->code != MEDIA_BUS_FMT_Y8_1X8 && + sink->code != MEDIA_BUS_FMT_Y10_1X10) { left += 2; right -= 2; top += 2; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2093 @ static int preview_init_formats(struct v memset(&format, 0, sizeof(format)); format.pad = PREV_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; preview_set_format(sd, fh, &format); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispresizer.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispresizer.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispresizer.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:201 @ static void resizer_set_bilinear(struct * @res: Device context. * @pixelcode: pixel code. */ -static void resizer_set_ycpos(struct isp_res_device *res, - enum v4l2_mbus_pixelcode pixelcode) +static void resizer_set_ycpos(struct isp_res_device *res, u32 pixelcode) { struct isp_device *isp = to_isp_device(res); switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_YCPOS); break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_YCPOS); break; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1350 @ static int resizer_set_selection(struct /* resizer pixel formats */ static const unsigned int resizer_formats[] = { - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; static unsigned int resizer_max_in_width(struct isp_res_device *res) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1387 @ static void resizer_try_format(struct is switch (pad) { case RESZ_PAD_SINK: - if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 && - fmt->code != V4L2_MBUS_FMT_UYVY8_1X16) - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; + if (fmt->code != MEDIA_BUS_FMT_YUYV8_1X16 && + fmt->code != MEDIA_BUS_FMT_UYVY8_1X16) + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH, resizer_max_in_width(res)); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1573 @ static int resizer_init_formats(struct v memset(&format, 0, sizeof(format)); format.pad = RESZ_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_YUYV8_1X16; + format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; format.format.width = 4096; format.format.height = 4096; resizer_set_format(sd, fh, &format); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispvideo.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispvideo.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispvideo.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:42 @ * corresponding in-memory formats to the table below!!! */ static struct isp_format_info formats[] = { - { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, 1, }, - { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y10, 10, 2, }, - { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y12, 12, 2, }, - { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8, 1, }, - { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8, 1, }, - { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8, 1, }, - { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8, 1, }, - { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR10_1X10, 0, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, 0, V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGBRG10_1X10, 0, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_1X10, 0, V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, 0, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, 0, V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, - V4L2_MBUS_FMT_SRGGB10_1X10, 0, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, 0, V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR10, 10, 2, }, - { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG10, 10, 2, }, - { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG10, 10, 2, }, - { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB10, 10, 2, }, - { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR12, 12, 2, }, - { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG12, 12, 2, }, - { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG12, 12, 2, }, - { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB12, 12, 2, }, - { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_UYVY8_1X16, 0, + { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, 0, V4L2_PIX_FMT_UYVY, 16, 2, }, - { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, 0, + { MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, 0, V4L2_PIX_FMT_YUYV, 16, 2, }, - { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, 0, + { MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, 0, V4L2_PIX_FMT_UYVY, 8, 2, }, - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_YUYV8_2X8, 0, + { MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, 0, V4L2_PIX_FMT_YUYV, 8, 2, }, /* Empty entry to catch the unsupported pixel code (0) used by the CCDC * module and avoid NULL pointer dereferences. @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:117 @ static struct isp_format_info formats[] { 0, } }; -const struct isp_format_info * -omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) +const struct isp_format_info *omap3isp_video_format_info(u32 code) { unsigned int i; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispvideo.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/omap3isp/ispvideo.h +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/omap3isp/ispvideo.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:47 @ struct v4l2_pix_format; * @bpp: Bytes per pixel (when stored in memory) */ struct isp_format_info { - enum v4l2_mbus_pixelcode code; - enum v4l2_mbus_pixelcode truncated; - enum v4l2_mbus_pixelcode uncompressed; - enum v4l2_mbus_pixelcode flavor; + u32 code; + u32 truncated; + u32 uncompressed; + u32 flavor; u32 pixelformat; unsigned int width; unsigned int bpp; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:209 @ void omap3isp_video_resume(struct isp_vi struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); const struct isp_format_info * -omap3isp_video_format_info(enum v4l2_mbus_pixelcode code); +omap3isp_video_format_info(u32 code); #endif /* OMAP3_ISP_VIDEO_H */ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/s3c-camif/camif-capture.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/s3c-camif/camif-capture.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/s3c-camif/camif-capture.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1221 @ void s3c_camif_unregister_video_node(str } /* Media bus pixel formats supported at the camif input */ -static const enum v4l2_mbus_pixelcode camif_mbus_formats[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_YVYU8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_VYUY8_2X8, +static const u32 camif_mbus_formats[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, }; /* Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/s3c-camif/camif-regs.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/s3c-camif/camif-regs.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/s3c-camif/camif-regs.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:99 @ void camif_hw_set_effect(struct camif_de } static const u32 src_pixfmt_map[8][2] = { - { V4L2_MBUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR }, - { V4L2_MBUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB }, - { V4L2_MBUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY }, - { V4L2_MBUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY }, + { MEDIA_BUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR }, + { MEDIA_BUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB }, + { MEDIA_BUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY }, + { MEDIA_BUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY }, }; /* Set camera input pixel format and resolution */ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/s5p-tv/hdmi_drv.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/s5p-tv/hdmi_drv.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/s5p-tv/hdmi_drv.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:663 @ static int hdmi_g_mbus_fmt(struct v4l2_s memset(fmt, 0, sizeof(*fmt)); fmt->width = t->hact.end - t->hact.beg; fmt->height = t->vact[0].end - t->vact[0].beg; - fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */ + fmt->code = MEDIA_BUS_FMT_FIXED; /* means RGB888 */ fmt->colorspace = V4L2_COLORSPACE_SRGB; if (t->interlaced) { fmt->field = V4L2_FIELD_INTERLACED; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/s5p-tv/sdo_drv.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/s5p-tv/sdo_drv.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/s5p-tv/sdo_drv.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:173 @ static int sdo_g_mbus_fmt(struct v4l2_su /* all modes are 720 pixels wide */ fmt->width = 720; fmt->height = sdev->fmt->height; - fmt->code = V4L2_MBUS_FMT_FIXED; + fmt->code = MEDIA_BUS_FMT_FIXED; fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_JPEG; return 0; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/sh_vou.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/sh_vou.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/sh_vou.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:683 @ static int sh_vou_s_fmt_vid_out(struct f struct sh_vou_geometry geo; struct v4l2_mbus_framefmt mbfmt = { /* Revisit: is this the correct code? */ - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .field = V4L2_FIELD_INTERLACED, .colorspace = V4L2_COLORSPACE_SMPTE170M, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:736 @ static int sh_vou_s_fmt_vid_out(struct f /* Sanity checks */ if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || (unsigned)mbfmt.height > img_height_max || - mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) + mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; if (mbfmt.width != geo.output.width || @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:946 @ static int sh_vou_s_crop(struct file *fi struct sh_vou_geometry geo; struct v4l2_mbus_framefmt mbfmt = { /* Revisit: is this the correct code? */ - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .field = V4L2_FIELD_INTERLACED, .colorspace = V4L2_COLORSPACE_SMPTE170M, }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:997 @ static int sh_vou_s_crop(struct file *fi /* Sanity checks */ if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || (unsigned)mbfmt.height > img_height_max || - mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) + mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; geo.output.width = mbfmt.width; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/atmel-isi.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/atmel-isi.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/atmel-isi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:108 @ static u32 isi_readl(struct atmel_isi *i } static int configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, enum v4l2_mbus_pixelcode code) + u32 height, u32 code) { u32 cfg2, cr; switch (code) { /* YUV, including grey */ - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: cr = ISI_CFG2_GRAYSCALE; break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_3; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_2; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_1; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cr = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:230 @ static int atmel_isi_wait_status(struct } timeout = wait_for_completion_timeout(&isi->complete, - msecs_to_jiffies(100)); + msecs_to_jiffies(500)); if (timeout == 0) return -ETIMEDOUT; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:648 @ static int isi_camera_get_formats(struct struct v4l2_subdev *sd = soc_camera_to_subdev(icd); int formats = 0, ret; /* sensor format */ - enum v4l2_mbus_pixelcode code; + u32 code; /* soc camera host format */ const struct soc_mbus_pixelfmt *fmt; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:673 @ static int isi_camera_get_formats(struct } switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: formats++; if (xlate) { xlate->host_fmt = &isi_camera_formats[0]; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:842 @ static int isi_camera_set_bus_param(stru if (isi->pdata.full_mode) cfg1 |= ISI_CFG1_FULL_MODE; + cfg1 |= ISI_CFG1_THMASK_BEATS_16; + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); return 0; } +static int isi_camera_set_parm(struct soc_camera_device *icd, struct v4l2_streamparm *parm) +{ + return 0; +} + static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add = isi_camera_add_device, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:868 @ static struct soc_camera_host_ops isi_so .poll = isi_camera_poll, .querycap = isi_camera_querycap, .set_bus_param = isi_camera_set_bus_param, + .set_parm = isi_camera_set_parm, + .get_parm = isi_camera_set_parm, }; /* -----------------------------------------------------------------------*/ Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/mx2_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/mx2_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/mx2_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:214 @ struct emma_prp_resize { /* prp configuration for a client-host fmt pair */ struct mx2_fmt_cfg { - enum v4l2_mbus_pixelcode in_fmt; + u32 in_fmt; u32 out_fmt; struct mx2_prp_cfg cfg; }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:312 @ static struct mx2_fmt_cfg mx27_emma_prp_ } }, { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, + .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8, .out_fmt = V4L2_PIX_FMT_YUYV, .cfg = { .channel = 1, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:326 @ static struct mx2_fmt_cfg mx27_emma_prp_ } }, { - .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8, + .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8, .out_fmt = V4L2_PIX_FMT_YUYV, .cfg = { .channel = 1, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:340 @ static struct mx2_fmt_cfg mx27_emma_prp_ } }, { - .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8, + .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8, .out_fmt = V4L2_PIX_FMT_YUV420, .cfg = { .channel = 2, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:354 @ static struct mx2_fmt_cfg mx27_emma_prp_ } }, { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, + .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8, .out_fmt = V4L2_PIX_FMT_YUV420, .cfg = { .channel = 2, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:369 @ static struct mx2_fmt_cfg mx27_emma_prp_ }, }; -static struct mx2_fmt_cfg *mx27_emma_prp_get_format( - enum v4l2_mbus_pixelcode in_fmt, - u32 out_fmt) +static struct mx2_fmt_cfg *mx27_emma_prp_get_format(u32 in_fmt, u32 out_fmt) { int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:946 @ static int mx2_camera_get_formats(struct struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_mbus_pixelfmt *fmt; struct device *dev = icd->parent; - enum v4l2_mbus_pixelcode code; + u32 code; int ret, formats = 0; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:960 @ static int mx2_camera_get_formats(struct return 0; } - if (code == V4L2_MBUS_FMT_YUYV8_2X8 || - code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_YUYV8_2X8 || + code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:969 @ static int mx2_camera_get_formats(struct * soc_mediabus.c */ xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_1_5X8); + soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_1_5X8); xlate->code = code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", xlate->host_fmt->name, code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:977 @ static int mx2_camera_get_formats(struct } } - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); + soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_2X8); xlate->code = code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", xlate->host_fmt->name, code); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/mx3_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/mx3_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/mx3_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:659 @ static int mx3_camera_get_formats(struct struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:680 @ static int mx3_camera_get_formats(struct return 0; switch (code) { - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[0]; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:690 @ static int mx3_camera_get_formats(struct mx3_camera_formats[0].name, code); } break; - case V4L2_MBUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_Y10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[1]; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/omap1_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/omap1_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/omap1_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:143 @ /* buffer for one video frame */ struct omap1_cam_buf { struct videobuf_buffer vb; - enum v4l2_mbus_pixelcode code; + u32 code; int inwork; struct scatterlist *sgbuf; int sgcount; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:983 @ static void omap1_cam_clock_stop(struct /* Duplicate standard formats based on host capability of byte swapping */ static const struct soc_mbus_lookup omap1_cam_formats[] = { { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:993 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1003 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1013 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1023 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, .name = "RGB555", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1033 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555X, .name = "RGB555X", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1043 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1053 @ static const struct soc_mbus_lookup omap .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565X, .name = "RGB565X", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1071 @ static int omap1_cam_get_formats(struct struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1091 @ static int omap1_cam_get_formats(struct return 0; switch (code) { - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: formats++; if (xlate) { xlate->host_fmt = soc_mbus_find_fmtdesc(code, Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/pxa_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/pxa_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/pxa_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:190 @ struct pxa_cam_dma { struct pxa_buffer { /* common v4l buffer stuff -- must be first */ struct videobuf_buffer vb; - enum v4l2_mbus_pixelcode code; + u32 code; /* our descriptor lists for Y, U and V channels */ struct pxa_cam_dma dmas[3]; int inwork; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1256 @ static int pxa_camera_get_formats(struct struct device *dev = icd->parent; int formats = 0, ret; struct pxa_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1286 @ static int pxa_camera_get_formats(struct } switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: formats++; if (xlate) { xlate->host_fmt = &pxa_camera_formats[0]; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1295 @ static int pxa_camera_get_formats(struct dev_dbg(dev, "Providing format %s using code %d\n", pxa_camera_formats[0].name, code); } - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_RGB565_2X8_LE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: if (xlate) dev_dbg(dev, "Providing format %s packed\n", fmt->name); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/rcar_vin.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/rcar_vin.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/rcar_vin.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:275 @ static int rcar_vin_setup(struct rcar_vi /* input interface */ switch (icd->current_fmt->code) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; break; - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:924 @ static int rcar_vin_get_formats(struct s int ret, k, n; int formats = 0; struct rcar_vin_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1013 @ static int rcar_vin_get_formats(struct s cam->extra_fmt = NULL; switch (code) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV10_2X10: if (cam->extra_fmt) break; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:152 @ struct sh_mobile_ceu_cam { /* Camera cropping rectangle */ struct v4l2_rect rect; const struct soc_mbus_pixelfmt *extra_fmt; - enum v4l2_mbus_pixelcode code; + u32 code; }; static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:864 @ static int sh_mobile_ceu_set_bus_param(s case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV61: switch (cam->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ break; default: @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1051 @ static int sh_mobile_ceu_get_formats(str int ret, k, n; int formats = 0; struct sh_mobile_ceu_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1144 @ static int sh_mobile_ceu_get_formats(str cam->extra_fmt = NULL; switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: if (cam->extra_fmt) break; Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/sh_mobile_csi2.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/sh_mobile_csi2.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:62 @ static int sh_csi2_try_fmt(struct v4l2_s switch (pdata->type) { case SH_CSI2C: switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */ - case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */ - case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */ - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_UYVY8_2X8: /* YUV422 */ + case MEDIA_BUS_FMT_YUYV8_1_5X8: /* YUV420 */ + case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: break; default: /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; } break; case SH_CSI2I: switch (mf->code) { - case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */ - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: - case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */ - case V4L2_MBUS_FMT_SBGGR12_1X12: /* RAW12 */ + case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: /* RAW10 */ + case MEDIA_BUS_FMT_SBGGR12_1X12: /* RAW12 */ break; default: /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; + mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; } break; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:107 @ static int sh_csi2_s_fmt(struct v4l2_sub return -EINVAL; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: tmp |= 0x1e; /* YUV422 8 bit */ break; - case V4L2_MBUS_FMT_YUYV8_1_5X8: + case MEDIA_BUS_FMT_YUYV8_1_5X8: tmp |= 0x18; /* YUV420 8 bit */ break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: tmp |= 0x21; /* RGB555 */ break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: tmp |= 0x22; /* RGB565 */ break; - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: tmp |= 0x2a; /* RAW8 */ break; default: Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/soc_camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:463 @ static int soc_camera_init_user_formats( struct soc_camera_host *ici = to_soc_camera_host(icd->parent); unsigned int i, fmts = 0, raw_fmts = 0; int ret; - enum v4l2_mbus_pixelcode code; + u32 code; while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) raw_fmts++; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:691 @ static int soc_camera_open(struct file * /* The camera could have been already on, try to reset */ if (sdesc->subdev_desc.reset) - sdesc->subdev_desc.reset(icd->pdev); + if (icd->control) + sdesc->subdev_desc.reset(icd->control); ret = soc_camera_add_device(icd); if (ret < 0) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1179 @ static void scan_add_host(struct soc_cam /* The camera could have been already on, try to reset */ if (ssdd->reset) - ssdd->reset(icd->pdev); + if (icd->control) + ssdd->reset(icd->control); icd->parent = ici->v4l2_dev.dev; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1466 @ static int soc_camera_async_bound(struct memcpy(&sdesc->subdev_desc, ssdd, sizeof(sdesc->subdev_desc)); if (ssdd->reset) - ssdd->reset(icd->pdev); + ssdd->reset(&client->dev); } icd->control = &client->dev; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1711 @ static void scan_of_host(struct soc_came continue; } - /* so we now have a remote node to connect */ - if (!i) - soc_of_bind(ici, epn, ren->parent); + soc_of_bind(ici, epn, ren->parent); of_node_put(epn); of_node_put(ren); - - if (i) { - dev_err(dev, "multiple subdevices aren't supported yet!\n"); - break; - } } } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_camera_platform.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/soc_camera_platform.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_camera_platform.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:65 @ static struct v4l2_subdev_core_ops platf }; static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_mediabus.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/soc_camera/soc_mediabus.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/soc_camera/soc_mediabus.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:20 @ static const struct soc_mbus_lookup mbus_fmt[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:30 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:40 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:50 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, .name = "RGB555", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:70 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555X, .name = "RGB555X", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:80 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:90 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565X, .name = "RGB565X", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:100 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB666_1X18, + .code = MEDIA_BUS_FMT_RGB666_1X18, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB666/32bpp", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:109 @ static const struct soc_mbus_lookup mbus .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_1X24, + .code = MEDIA_BUS_FMT_RGB888_1X24, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:118 @ static const struct soc_mbus_lookup mbus .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_2X12_BE, + .code = MEDIA_BUS_FMT_RGB888_2X12_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:127 @ static const struct soc_mbus_lookup mbus .order = SOC_MBUS_ORDER_BE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_2X12_LE, + .code = MEDIA_BUS_FMT_RGB888_2X12_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:136 @ static const struct soc_mbus_lookup mbus .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_SBGGR8_1X8, + .code = MEDIA_BUS_FMT_SBGGR8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR8, .name = "Bayer 8 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:146 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_1X10, + .code = MEDIA_BUS_FMT_SBGGR10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:156 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_Y8_1X8, + .code = MEDIA_BUS_FMT_Y8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_GREY, .name = "Grey", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:166 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_Y10_1X10, + .code = MEDIA_BUS_FMT_Y10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_Y10, .name = "Grey 10bit", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:176 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:186 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:196 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:206 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:216 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_JPEG, .name = "JPEG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:226 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB444, .name = "RGB444", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:236 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_1_5X8, + .code = MEDIA_BUS_FMT_YUYV8_1_5X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUV420, .name = "YUYV 4:2:0", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:246 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_1_5X8, + .code = MEDIA_BUS_FMT_YVYU8_1_5X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVU420, .name = "YVYU 4:2:0", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:256 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_UYVY8_1X16, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY 16bit", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:266 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_1X16, + .code = MEDIA_BUS_FMT_VYUY8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY 16bit", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:276 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_1X16, + .code = MEDIA_BUS_FMT_YUYV8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV 16bit", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:286 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_1X16, + .code = MEDIA_BUS_FMT_YVYU8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU 16bit", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:296 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG8_1X8, + .code = MEDIA_BUS_FMT_SGRBG8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG8, .name = "Bayer 8 GRBG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:306 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, + .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8, .name = "Bayer 10 BGGR DPCM 8", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:316 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGBRG10_1X10, + .code = MEDIA_BUS_FMT_SGBRG10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SGBRG10, .name = "Bayer 10 GBRG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:326 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG10, .name = "Bayer 10 GRBG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:336 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SRGGB10_1X10, + .code = MEDIA_BUS_FMT_SRGGB10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SRGGB10, .name = "Bayer 10 RGGB", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:346 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR12_1X12, + .code = MEDIA_BUS_FMT_SBGGR12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR12, .name = "Bayer 12 BGGR", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:356 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGBRG12_1X12, + .code = MEDIA_BUS_FMT_SGBRG12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SGBRG12, .name = "Bayer 12 GBRG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:366 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG12_1X12, + .code = MEDIA_BUS_FMT_SGRBG12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG12, .name = "Bayer 12 GRBG", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:376 @ static const struct soc_mbus_lookup mbus .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SRGGB12_1X12, + .code = MEDIA_BUS_FMT_SRGGB12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SRGGB12, .name = "Bayer 12 RGGB", @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:461 @ s32 soc_mbus_image_size(const struct soc EXPORT_SYMBOL(soc_mbus_image_size); const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( - enum v4l2_mbus_pixelcode code, + u32 code, const struct soc_mbus_lookup *lookup, int n) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:476 @ const struct soc_mbus_pixelfmt *soc_mbus EXPORT_SYMBOL(soc_mbus_find_fmtdesc); const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( - enum v4l2_mbus_pixelcode code) + u32 code) { return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt)); } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/via-camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/via-camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/via-camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:104 @ struct via_camera { */ struct v4l2_pix_format sensor_format; struct v4l2_pix_format user_format; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; }; /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:146 @ static struct via_format { __u8 *desc; __u32 pixelformat; int bpp; /* Bytes per pixel */ - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; } via_formats[] = { { .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, }, /* RGB444 and Bayer should be doable, but have never been @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:852 @ static const struct v4l2_pix_format viac .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, }; -static const enum v4l2_mbus_pixelcode via_def_mbus_code = V4L2_MBUS_FMT_YUYV8_2X8; +static const u32 via_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_fmtdesc *fmt) Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_bru.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_bru.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_bru.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:190 @ static int bru_enum_mbus_code(struct v4l struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:218 @ static int bru_enum_frame_size(struct v4 if (fse->index) return -EINVAL; - if (fse->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fse->code != V4L2_MBUS_FMT_AYUV8_1X32) + if (fse->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fse->code != MEDIA_BUS_FMT_AYUV8_1X32) return -EINVAL; fse->min_width = BRU_MIN_SIZE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:264 @ static void bru_try_format(struct vsp1_b switch (pad) { case BRU_PAD_SINK(0): /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; break; default: Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_hsit.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_hsit.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_hsit.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:73 @ static int hsit_enum_mbus_code(struct v4 if ((code->pad == HSIT_PAD_SINK && !hsit->inverse) | (code->pad == HSIT_PAD_SOURCE && hsit->inverse)) - code->code = V4L2_MBUS_FMT_ARGB8888_1X32; + code->code = MEDIA_BUS_FMT_ARGB8888_1X32; else - code->code = V4L2_MBUS_FMT_AHSV8888_1X32; + code->code = MEDIA_BUS_FMT_AHSV8888_1X32; return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:139 @ static int hsit_set_format(struct v4l2_s return 0; } - format->code = hsit->inverse ? V4L2_MBUS_FMT_AHSV8888_1X32 - : V4L2_MBUS_FMT_ARGB8888_1X32; + format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32 + : MEDIA_BUS_FMT_ARGB8888_1X32; format->width = clamp_t(unsigned int, fmt->format.width, HSIT_MIN_SIZE, HSIT_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:154 @ static int hsit_set_format(struct v4l2_s format = vsp1_entity_get_pad_format(&hsit->entity, fh, HSIT_PAD_SOURCE, fmt->which); *format = fmt->format; - format->code = hsit->inverse ? V4L2_MBUS_FMT_ARGB8888_1X32 - : V4L2_MBUS_FMT_AHSV8888_1X32; + format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 + : MEDIA_BUS_FMT_AHSV8888_1X32; return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_lif.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_lif.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_lif.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:81 @ static int lif_enum_mbus_code(struct v4l struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->pad == LIF_PAD_SINK) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:150 @ static int lif_set_format(struct v4l2_su struct v4l2_mbus_framefmt *format; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, fmt->which); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_lut.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_lut.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_lut.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:89 @ static int lut_enum_mbus_code(struct v4l struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AHSV8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AHSV8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:161 @ static int lut_set_format(struct v4l2_su struct v4l2_mbus_framefmt *format; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AHSV8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, fmt->which); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_rwpf.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_rwpf.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_rwpf.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:32 @ int vsp1_rwpf_enum_mbus_code(struct v4l2 struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->index >= ARRAY_SIZE(codes)) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:106 @ int vsp1_rwpf_set_format(struct v4l2_sub struct v4l2_rect *crop; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, fmt->which); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_sru.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_sru.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_sru.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:142 @ static int sru_s_stream(struct v4l2_subd input = &sru->entity.formats[SRU_PAD_SINK]; output = &sru->entity.formats[SRU_PAD_SOURCE]; - if (input->code == V4L2_MBUS_FMT_ARGB8888_1X32) + if (input->code == MEDIA_BUS_FMT_ARGB8888_1X32) ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3 | VI6_SRU_CTRL0_PARAM4; else @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:173 @ static int sru_enum_mbus_code(struct v4l struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:251 @ static void sru_try_format(struct vsp1_s switch (pad) { case SRU_PAD_SINK: /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; fmt->width = clamp(fmt->width, SRU_MIN_SIZE, SRU_MAX_SIZE); fmt->height = clamp(fmt->height, SRU_MIN_SIZE, SRU_MAX_SIZE); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_uds.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_uds.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_uds.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:176 @ static int uds_enum_mbus_code(struct v4l struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->pad == UDS_PAD_SINK) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:249 @ static void uds_try_format(struct vsp1_u switch (pad) { case UDS_PAD_SINK: /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; fmt->width = clamp(fmt->width, UDS_MIN_SIZE, UDS_MAX_SIZE); fmt->height = clamp(fmt->height, UDS_MIN_SIZE, UDS_MAX_SIZE); Index: linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_video.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/platform/vsp1/vsp1_video.c +++ linux-3.18.13-rt10-r7s4/drivers/media/platform/vsp1/vsp1_video.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:51 @ */ static const struct vsp1_format_info vsp1_video_formats[] = { - { V4L2_PIX_FMT_RGB332, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 8, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ARGB444, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB444, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_ARGB555, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB555, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_RGB565, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_BGR24, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 24, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_RGB24, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 24, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ABGR32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, 1, { 32, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XBGR32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, 1, { 32, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ARGB32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 32, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 32, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_UYVY, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, false, false, 2, 1, false }, - { V4L2_PIX_FMT_VYUY, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, false, true, 2, 1, false }, - { V4L2_PIX_FMT_YUYV, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, true, false, 2, 1, false }, - { V4L2_PIX_FMT_YVYU, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, true, true, 2, 1, false }, - { V4L2_PIX_FMT_NV12M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, false, 2, 2, false }, - { V4L2_PIX_FMT_NV21M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, true, 2, 2, false }, - { V4L2_PIX_FMT_NV16M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, false, 2, 1, false }, - { V4L2_PIX_FMT_NV61M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, true, 2, 1, false }, - { V4L2_PIX_FMT_YUV420M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 3, { 8, 8, 8 }, false, false, 2, 2, false }, Index: linux-3.18.13-rt10-r7s4/drivers/media/usb/cx231xx/cx231xx-417.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/usb/cx231xx/cx231xx-417.c +++ linux-3.18.13-rt10-r7s4/drivers/media/usb/cx231xx/cx231xx-417.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1881 @ static int cx231xx_s_video_encoding(stru /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt); return 0; } Index: linux-3.18.13-rt10-r7s4/drivers/media/usb/cx231xx/cx231xx-video.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/usb/cx231xx/cx231xx-video.c +++ linux-3.18.13-rt10-r7s4/drivers/media/usb/cx231xx/cx231xx-video.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:970 @ static int vidioc_s_fmt_vid_cap(struct f dev->height = f->fmt.pix.height; dev->format = fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1015 @ static int vidioc_s_std(struct file *fil resolution (since a standard change effects things like the number of lines in VACT, etc) */ memset(&mbus_fmt, 0, sizeof(mbus_fmt)); - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = dev->width; mbus_fmt.height = dev->height; call_all(dev, video, s_mbus_fmt, &mbus_fmt); Index: linux-3.18.13-rt10-r7s4/drivers/media/usb/em28xx/em28xx-camera.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/usb/em28xx/em28xx-camera.c +++ linux-3.18.13-rt10-r7s4/drivers/media/usb/em28xx/em28xx-camera.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:433 @ int em28xx_init_camera(struct em28xx *de break; } - fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt.code = MEDIA_BUS_FMT_YUYV8_2X8; fmt.width = 640; fmt.height = 480; v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); Index: linux-3.18.13-rt10-r7s4/drivers/media/usb/go7007/go7007-v4l2.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/usb/go7007/go7007-v4l2.c +++ linux-3.18.13-rt10-r7s4/drivers/media/usb/go7007/go7007-v4l2.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:255 @ static int set_capture_size(struct go700 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { struct v4l2_mbus_framefmt mbus_fmt; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = fmt ? fmt->fmt.pix.width : width; mbus_fmt.height = height; go->encoder_h_halve = 0; Index: linux-3.18.13-rt10-r7s4/drivers/media/usb/pvrusb2/pvrusb2-hdw.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ linux-3.18.13-rt10-r7s4/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2969 @ static void pvr2_subdev_update(struct pv memset(&fmt, 0, sizeof(fmt)); fmt.width = hdw->res_hor_val; fmt.height = hdw->res_ver_val; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", fmt.width, fmt.height); v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); Index: linux-3.18.13-rt10-r7s4/drivers/mfd/atmel-hlcdc.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/mfd/atmel-hlcdc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * 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. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/mfd/atmel-hlcdc.h> +#include <linux/mfd/core.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define ATMEL_HLCDC_REG_MAX (0x4000 - 0x4) + +static const struct mfd_cell atmel_hlcdc_cells[] = { + { + .name = "atmel-hlcdc-pwm", + .of_compatible = "atmel,hlcdc-pwm", + }, + { + .name = "atmel-hlcdc-dc", + .of_compatible = "atmel,hlcdc-display-controller", + }, +}; + +static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + void __iomem *regs = context; + + if (reg <= ATMEL_HLCDC_DIS) { + while (readl(regs + ATMEL_HLCDC_SR) & ATMEL_HLCDC_SIP) + udelay(1); + } + + writel(val, regs + reg); + + return 0; +} + +static int regmap_atmel_hlcdc_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + void __iomem *regs = context; + + *val = readl(regs + reg); + + return 0; +} + +static const struct regmap_config atmel_hlcdc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = ATMEL_HLCDC_REG_MAX, + .reg_write = regmap_atmel_hlcdc_reg_write, + .reg_read = regmap_atmel_hlcdc_reg_read, + .fast_io = true, +}; + +static int atmel_hlcdc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct atmel_hlcdc *hlcdc; + struct resource *res; + void __iomem *regs; + + hlcdc = devm_kzalloc(dev, sizeof(*hlcdc), GFP_KERNEL); + if (!hlcdc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + hlcdc->irq = platform_get_irq(pdev, 0); + if (hlcdc->irq < 0) + return hlcdc->irq; + + hlcdc->periph_clk = devm_clk_get(dev, "periph_clk"); + if (IS_ERR(hlcdc->periph_clk)) { + dev_err(dev, "failed to get peripheral clock\n"); + return PTR_ERR(hlcdc->periph_clk); + } + + hlcdc->sys_clk = devm_clk_get(dev, "sys_clk"); + if (IS_ERR(hlcdc->sys_clk)) { + dev_err(dev, "failed to get system clock\n"); + return PTR_ERR(hlcdc->sys_clk); + } + + hlcdc->slow_clk = devm_clk_get(dev, "slow_clk"); + if (IS_ERR(hlcdc->slow_clk)) { + dev_err(dev, "failed to get slow clock\n"); + return PTR_ERR(hlcdc->slow_clk); + } + + hlcdc->regmap = devm_regmap_init(dev, NULL, regs, + &atmel_hlcdc_regmap_config); + if (IS_ERR(hlcdc->regmap)) + return PTR_ERR(hlcdc->regmap); + + dev_set_drvdata(dev, hlcdc); + + return mfd_add_devices(dev, -1, atmel_hlcdc_cells, + ARRAY_SIZE(atmel_hlcdc_cells), + NULL, 0, NULL); +} + +static int atmel_hlcdc_remove(struct platform_device *pdev) +{ + mfd_remove_devices(&pdev->dev); + + return 0; +} + +static const struct of_device_id atmel_hlcdc_match[] = { + { .compatible = "atmel,at91sam9n12-hlcdc" }, + { .compatible = "atmel,at91sam9x5-hlcdc" }, + { .compatible = "atmel,sama5d3-hlcdc" }, + { .compatible = "atmel,sama5d4-hlcdc" }, + { /* sentinel */ }, +}; + +static struct platform_driver atmel_hlcdc_driver = { + .probe = atmel_hlcdc_probe, + .remove = atmel_hlcdc_remove, + .driver = { + .name = "atmel-hlcdc", + .of_match_table = atmel_hlcdc_match, + }, +}; +module_platform_driver(atmel_hlcdc_driver); + +MODULE_ALIAS("platform:atmel-hlcdc"); +MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); +MODULE_DESCRIPTION("Atmel HLCDC driver"); +MODULE_LICENSE("GPL v2"); Index: linux-3.18.13-rt10-r7s4/drivers/mfd/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mfd/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/mfd/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:62 @ config MFD_AAT2870_CORE additional drivers must be enabled in order to use the functionality of the device. +config MFD_ATMEL_HLCDC + tristate "Atmel HLCDC (High-end LCD Controller)" + select MFD_CORE + select REGMAP_MMIO + depends on OF + help + If you say yes here you get support for the HLCDC block. + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the + functionality of the device. + config MFD_BCM590XX tristate "Broadcom BCM590xx PMUs" select MFD_CORE Index: linux-3.18.13-rt10-r7s4/drivers/mfd/Makefile =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mfd/Makefile +++ linux-3.18.13-rt10-r7s4/drivers/mfd/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:160 @ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o +obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o Index: linux-3.18.13-rt10-r7s4/drivers/misc/atmel-ssc.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/misc/atmel-ssc.c +++ linux-3.18.13-rt10-r7s4/drivers/misc/atmel-ssc.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:60 @ struct ssc_device *ssc_request(unsigned ssc->user++; spin_unlock(&user_lock); - clk_prepare_enable(ssc->clk); + clk_prepare(ssc->clk); return ssc; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:80 @ void ssc_free(struct ssc_device *ssc) spin_unlock(&user_lock); if (disable_clk) - clk_disable_unprepare(ssc->clk); + clk_unprepare(ssc->clk); } EXPORT_SYMBOL(ssc_free); Index: linux-3.18.13-rt10-r7s4/drivers/misc/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/misc/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/misc/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:78 @ config ATMEL_TCB_CLKSRC config ATMEL_TCB_CLKSRC_BLOCK int depends on ATMEL_TCB_CLKSRC - prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || CPU_AT32AP700X + prompt "TC Block" if CPU_AT32AP700X default 0 range 0 1 help Index: linux-3.18.13-rt10-r7s4/drivers/mmc/host/atmel-mci.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mmc/host/atmel-mci.c +++ linux-3.18.13-rt10-r7s4/drivers/mmc/host/atmel-mci.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:33 @ #include <linux/stat.h> #include <linux/types.h> #include <linux/platform_data/atmel.h> +#include <linux/platform_data/mmc-atmel-mci.h> #include <linux/mmc/host.h> #include <linux/mmc/sdio.h> -#include <mach/atmel-mci.h> #include <linux/atmel-mci.h> #include <linux/atmel_pdc.h> +#include <linux/pm.h> +#include <linux/pinctrl/consumer.h> #include <asm/cacheflush.h> #include <asm/io.h> @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:565 @ atmci_of_init(struct platform_device *pd pdata->slot[slot_id].detect_is_active_high = of_property_read_bool(cnp, "cd-inverted"); + pdata->slot[slot_id].non_removable = + of_property_read_bool(cnp, "non-removable"); + pdata->slot[slot_id].wp_pin = of_get_named_gpio(cnp, "wp-gpios", 0); } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2145 @ static irqreturn_t atmci_detect_interrup return IRQ_HANDLED; } -static int __init atmci_init_slot(struct atmel_mci *host, +static int atmci_init_slot(struct atmel_mci *host, struct mci_slot_pdata *slot_data, unsigned int id, u32 sdc_reg, u32 sdio_irq) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2214 @ static int __init atmci_init_slot(struct } } - if (!gpio_is_valid(slot->detect_pin)) - mmc->caps |= MMC_CAP_NEEDS_POLL; + if (!gpio_is_valid(slot->detect_pin)) { + if (slot_data->non_removable) + mmc->caps |= MMC_CAP_NONREMOVABLE; + else + mmc->caps |= MMC_CAP_NEEDS_POLL; + } if (gpio_is_valid(slot->wp_pin)) { if (devm_gpio_request(&host->pdev->dev, slot->wp_pin, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2277 @ static void atmci_cleanup_slot(struct at mmc_free_host(slot->mmc); } -static bool atmci_filter(struct dma_chan *chan, void *pdata) -{ - struct mci_platform_data *sl_pdata = pdata; - struct mci_dma_data *sl; - - if (!sl_pdata) - return false; - - sl = sl_pdata->dma_slave; - if (sl && find_slave_dev(sl) == chan->device->dev) { - chan->private = slave_data_ptr(sl); - return true; - } else { - return false; - } -} - -static bool atmci_configure_dma(struct atmel_mci *host) +static int atmci_configure_dma(struct atmel_mci *host) { - struct mci_platform_data *pdata; - dma_cap_mask_t mask; - - if (host == NULL) - return false; + host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev, + "rxtx"); + if (IS_ERR(host->dma.chan)) + return PTR_ERR(host->dma.chan); + + dev_info(&host->pdev->dev, "using %s for DMA transfers\n", + dma_chan_name(host->dma.chan)); + + host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; + host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + host->dma_conf.src_maxburst = 1; + host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; + host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + host->dma_conf.dst_maxburst = 1; + host->dma_conf.device_fc = false; - pdata = host->pdev->dev.platform_data; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata, - &host->pdev->dev, "rxtx"); - if (!host->dma.chan) { - dev_warn(&host->pdev->dev, "no DMA channel available\n"); - return false; - } else { - dev_info(&host->pdev->dev, - "using %s for DMA transfers\n", - dma_chan_name(host->dma.chan)); - - host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; - host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - host->dma_conf.src_maxburst = 1; - host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; - host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - host->dma_conf.dst_maxburst = 1; - host->dma_conf.device_fc = false; - return true; - } + return 0; } /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2303 @ static bool atmci_configure_dma(struct a * HSMCI provides DMA support and a new config register but no more supports * PDC. */ -static void __init atmci_get_cap(struct atmel_mci *host) +static void atmci_get_cap(struct atmel_mci *host) { unsigned int version; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2352 @ static void __init atmci_get_cap(struct } } -static int __init atmci_probe(struct platform_device *pdev) +static int atmci_probe(struct platform_device *pdev) { struct mci_platform_data *pdata; struct atmel_mci *host; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2411 @ static int __init atmci_probe(struct pla /* Get MCI capabilities and set operations according to it */ atmci_get_cap(host); - if (atmci_configure_dma(host)) { + ret = atmci_configure_dma(host); + if (ret == -EPROBE_DEFER) + goto err_dma_probe_defer; + if (ret == 0) { host->prepare_data = &atmci_prepare_data_dma; host->submit_data = &atmci_submit_data_dma; host->stop_transfer = &atmci_stop_transfer_dma; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2485 @ err_dma_alloc: } err_init_slot: del_timer_sync(&host->timer); - if (host->dma.chan) + if (!IS_ERR(host->dma.chan)) dma_release_channel(host->dma.chan); +err_dma_probe_defer: free_irq(irq, host); return ret; } -static int __exit atmci_remove(struct platform_device *pdev) +static int atmci_remove(struct platform_device *pdev) { struct atmel_mci *host = platform_get_drvdata(pdev); unsigned int i; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2513 @ static int __exit atmci_remove(struct pl clk_disable_unprepare(host->mck); del_timer_sync(&host->timer); - if (host->dma.chan) + if (!IS_ERR(host->dma.chan)) dma_release_channel(host->dma.chan); free_irq(platform_get_irq(pdev, 0), host); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2522 @ static int __exit atmci_remove(struct pl } static struct platform_driver atmci_driver = { - .remove = __exit_p(atmci_remove), + .probe = atmci_probe, + .remove = atmci_remove, .driver = { .name = "atmel_mci", .of_match_table = of_match_ptr(atmci_dt_ids), }, }; - -static int __init atmci_init(void) -{ - return platform_driver_probe(&atmci_driver, atmci_probe); -} - -static void __exit atmci_exit(void) -{ - platform_driver_unregister(&atmci_driver); -} - -late_initcall(atmci_init); /* try to load after dma driver when built-in */ -module_exit(atmci_exit); +module_platform_driver(atmci_driver); MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); Index: linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mtd/nand/atmel_nand.c +++ linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:66 @ module_param(on_flash_bbt, int, 0); #include "atmel_nand_ecc.h" /* Hardware ECC registers */ #include "atmel_nand_nfc.h" /* Nand Flash Controller definition */ +struct atmel_nand_caps { + bool pmecc_correct_erase_page; +}; + /* oob layout for large page size * bad block info is on bytes 0 and 1 * the bytes have to be consecutives to avoid @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:99 @ static struct nand_ecclayout atmel_oobin struct atmel_nfc { void __iomem *base_cmd_regs; void __iomem *hsmc_regs; - void __iomem *sram_bank0; + void *sram_bank0; dma_addr_t sram_bank0_phys; bool use_nfc_sram; bool write_by_sram; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:112 @ struct atmel_nfc { struct completion comp_xfer_done; /* Point to the sram bank which include readed data via NFC */ - void __iomem *data_in_sram; + void *data_in_sram; bool will_write_sram; }; static struct atmel_nfc nand_nfc; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:131 @ struct atmel_nand_host { struct atmel_nfc *nfc; + struct atmel_nand_caps *caps; bool has_pmecc; u8 pmecc_corr_cap; u16 pmecc_sector_size; + bool has_no_lookup_table; u32 pmecc_lookup_table_offset; u32 pmecc_lookup_table_offset_512; u32 pmecc_lookup_table_offset_1024; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:265 @ static int atmel_nand_set_enable_ready_p return res; } -static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) -{ - int i; - u32 *t = trg; - const __iomem u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - *t++ = readl_relaxed(s++); -} - -static void memcpy32_toio(void __iomem *trg, const void *src, int size) -{ - int i; - u32 __iomem *t = trg; - const u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - writel_relaxed(*s++, t++); -} - /* * Minimal-overhead PIO for data access. */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:274 @ static void atmel_read_buf8(struct mtd_i struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsb(nand_chip->IO_ADDR_R, buf, len); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:287 @ static void atmel_read_buf16(struct mtd_ struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:855 @ static int pmecc_correction(struct mtd_i struct atmel_nand_host *host = nand_chip->priv; int i, err_nbr; uint8_t *buf_pos; - int total_err = 0; + int max_bitflips = 0; + + /* If can correct bitfilps from erased page, do the normal check */ + if (host->caps->pmecc_correct_erase_page) + goto normal_check; for (i = 0; i < nand_chip->ecc.total; i++) if (ecc[i] != 0xff) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:886 @ normal_check: pmecc_correct_data(mtd, buf_pos, ecc, i, nand_chip->ecc.bytes, err_nbr); mtd->ecc_stats.corrected += err_nbr; - total_err += err_nbr; + max_bitflips = max_t(int, max_bitflips, err_nbr); } } pmecc_stat >>= 1; } - return total_err; + return max_bitflips; } static void pmecc_enable(struct atmel_nand_host *host, int ecc_op) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1105 @ static int pmecc_choose_ecc(struct atmel return 0; } +static inline int deg(unsigned int poly) +{ + /* polynomial degree is the most-significant bit index */ + return fls(poly) - 1; +} + +static int build_gf_tables(int mm, unsigned int poly, + int16_t *index_of, int16_t *alpha_to) +{ + unsigned int i, x = 1; + const unsigned int k = 1 << deg(poly); + unsigned int nn = (1 << mm) - 1; + + /* primitive polynomial must be of degree m */ + if (k != (1u << mm)) + return -EINVAL; + + for (i = 0; i < nn; i++) { + alpha_to[i] = x; + index_of[x] = i; + if (i && (x == 1)) + /* polynomial is not primitive (a^i=1 with 0<i<2^m-1) */ + return -EINVAL; + x <<= 1; + if (x & k) + x ^= poly; + } + alpha_to[nn] = 1; + index_of[0] = 0; + + return 0; +} + +static uint16_t *create_lookup_table(struct device *dev, int sector_size) +{ + int degree = (sector_size == 512) ? + PMECC_GF_DIMENSION_13 : + PMECC_GF_DIMENSION_14; + unsigned int poly = (sector_size == 512) ? + PMECC_GF_13_PRIMITIVE_POLY : + PMECC_GF_14_PRIMITIVE_POLY; + int table_size = (sector_size == 512) ? + PMECC_LOOKUP_TABLE_SIZE_512 : + PMECC_LOOKUP_TABLE_SIZE_1024; + + int16_t *addr = devm_kzalloc(dev, 2 * table_size * sizeof(uint16_t), + GFP_KERNEL); + if (addr && build_gf_tables(degree, poly, addr, addr + table_size)) + return NULL; + + return addr; +} + static int atmel_pmecc_nand_init_params(struct platform_device *pdev, struct atmel_nand_host *host) { struct mtd_info *mtd = &host->mtd; struct nand_chip *nand_chip = &host->nand_chip; struct resource *regs, *regs_pmerr, *regs_rom; + uint16_t *galois_table; int cap, sector_size, err_no; err_no = pmecc_choose_ecc(host, &cap, §or_size); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1210 @ static int atmel_pmecc_nand_init_params( regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3); host->pmecc_rom_base = devm_ioremap_resource(&pdev->dev, regs_rom); if (IS_ERR(host->pmecc_rom_base)) { - err_no = PTR_ERR(host->pmecc_rom_base); - goto err; + if (!host->has_no_lookup_table) + /* Don't display the information again */ + dev_err(host->dev, "Can not get I/O resource for ROM, will build a lookup table in runtime!\n"); + + host->has_no_lookup_table = true; + } + + if (host->has_no_lookup_table) { + /* Build the look-up table in runtime */ + galois_table = create_lookup_table(host->dev, sector_size); + if (!galois_table) { + dev_err(host->dev, "Failed to build a lookup table in runtime!\n"); + err_no = -EINVAL; + goto err; + } + + host->pmecc_rom_base = (void __iomem *)galois_table; + host->pmecc_lookup_table_offset = 0; } nand_chip->ecc.size = sector_size; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1486 @ static void atmel_nand_hwctl(struct mtd_ ecc_writel(host->ecc, CR, ATMEL_ECC_RST); } +static const struct of_device_id atmel_nand_dt_ids[]; + static int atmel_of_init_port(struct atmel_nand_host *host, struct device_node *np) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1497 @ static int atmel_of_init_port(struct atm struct atmel_nand_data *board = &host->board; enum of_gpio_flags flags = 0; + host->caps = (struct atmel_nand_caps *) + of_match_device(atmel_nand_dt_ids, host->dev)->data; + if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { if (val >= 32) { dev_err(host->dev, "invalid addr-offset %u\n", val); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1569 @ static int atmel_of_init_port(struct atm if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset", offset, 2) != 0) { - dev_err(host->dev, "Cannot get PMECC lookup table offset\n"); - return -EINVAL; + dev_err(host->dev, "Cannot get PMECC lookup table offset, will build a lookup table in runtime.\n"); + host->has_no_lookup_table = true; + /* Will build a lookup table and initialize the offset later */ + return 0; } if (!offset[0] && !offset[1]) { dev_err(host->dev, "Invalid PMECC lookup table offset\n"); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1755 @ static int nfc_send_command(struct atmel cmd, addr, cycle0); timeout = jiffies + msecs_to_jiffies(NFC_TIME_OUT_MS); - while (nfc_cmd_readl(NFCADDR_CMD_NFCBUSY, host->nfc->base_cmd_regs) - & NFCADDR_CMD_NFCBUSY) { + while (nfc_readl(host->nfc->hsmc_regs, SR) & NFC_SR_BUSY) { if (time_after(jiffies, timeout)) { dev_err(host->dev, - "Time out to wait CMD_NFCBUSY ready!\n"); + "Time out to wait for NFC ready!\n"); return -ETIMEDOUT; } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1968 @ static int nfc_sram_write_page(struct mt int cfg, len; int status = 0; struct atmel_nand_host *host = chip->priv; - void __iomem *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); + void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); /* Subpage write is not supported */ if (offset || (data_len < mtd->writesize)) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1979 @ static int nfc_sram_write_page(struct mt if (use_dma) { if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) != 0) /* Fall back to use cpu copy */ - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } else { - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } cfg = nfc_readl(host->nfc->hsmc_regs, CFG); if (unlikely(raw) && oob_required) { - memcpy32_toio(sram + len, chip->oob_poi, mtd->oobsize); + memcpy(sram + len, chip->oob_poi, mtd->oobsize); len += mtd->oobsize; nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); } else { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2304 @ static int atmel_nand_remove(struct plat return 0; } +static struct atmel_nand_caps at91rm9200_caps = { + .pmecc_correct_erase_page = false, +}; + +static struct atmel_nand_caps sama5d4_caps = { + .pmecc_correct_erase_page = true, +}; + static const struct of_device_id atmel_nand_dt_ids[] = { - { .compatible = "atmel,at91rm9200-nand" }, + { .compatible = "atmel,at91rm9200-nand", .data = &at91rm9200_caps }, + { .compatible = "atmel,sama5d4-nand", .data = &sama5d4_caps }, { /* sentinel */ } }; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2338 @ static int atmel_nand_nfc_probe(struct p nfc_sram = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (nfc_sram) { - nfc->sram_bank0 = devm_ioremap_resource(&pdev->dev, nfc_sram); + nfc->sram_bank0 = (void * __force) + devm_ioremap_resource(&pdev->dev, nfc_sram); if (IS_ERR(nfc->sram_bank0)) { dev_warn(&pdev->dev, "Fail to ioremap the NFC sram with error: %ld. So disable NFC sram.\n", PTR_ERR(nfc->sram_bank0)); Index: linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand_ecc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mtd/nand/atmel_nand_ecc.h +++ linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand_ecc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:145 @ #define PMECC_GF_DIMENSION_13 13 #define PMECC_GF_DIMENSION_14 14 +/* Primitive Polynomial used by PMECC */ +#define PMECC_GF_13_PRIMITIVE_POLY 0x201b +#define PMECC_GF_14_PRIMITIVE_POLY 0x4443 + #define PMECC_LOOKUP_TABLE_SIZE_512 0x2000 #define PMECC_LOOKUP_TABLE_SIZE_1024 0x4000 Index: linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand_nfc.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/mtd/nand/atmel_nand_nfc.h +++ linux-3.18.13-rt10-r7s4/drivers/mtd/nand/atmel_nand_nfc.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:38 @ #define NFC_CTRL_DISABLE (1 << 1) #define ATMEL_HSMC_NFC_SR 0x08 /* NFC Status Register */ +#define NFC_SR_BUSY (1 << 8) #define NFC_SR_XFR_DONE (1 << 16) #define NFC_SR_CMD_DONE (1 << 17) #define NFC_SR_DTOE (1 << 20) Index: linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/Kconfig =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/net/ethernet/cadence/Kconfig +++ linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:25 @ if NET_CADENCE config ARM_AT91_ETHER tristate "AT91RM9200 Ethernet support" - depends on HAS_DMA && (ARCH_AT91RM9200 || COMPILE_TEST) + depends on HAS_DMA && (ARCH_AT91 || COMPILE_TEST) select MACB ---help--- If you wish to compile a kernel for the AT91RM9200 and enable Index: linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/macb.c =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/net/ethernet/cadence/macb.c +++ linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/macb.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:69 @ static unsigned int macb_tx_ring_wrap(un return index & (TX_RING_SIZE - 1); } -static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index) +static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue, + unsigned int index) { - return &bp->tx_ring[macb_tx_ring_wrap(index)]; + return &queue->tx_ring[macb_tx_ring_wrap(index)]; } -static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index) +static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue, + unsigned int index) { - return &bp->tx_skb[macb_tx_ring_wrap(index)]; + return &queue->tx_skb[macb_tx_ring_wrap(index)]; } -static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index) +static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index) { dma_addr_t offset; offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc); - return bp->tx_ring_dma + offset; + return queue->tx_ring_dma + offset; } static unsigned int macb_rx_ring_wrap(unsigned int index) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:295 @ static void macb_handle_link_change(stru spin_unlock_irqrestore(&bp->lock, flags); - if (!IS_ERR(bp->tx_clk)) - macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); - if (status_change) { if (phydev->link) { + /* Update the TX clock rate if and only if the link is + * up and there has been a link change. + */ + if (!IS_ERR(bp->tx_clk)) + macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); + netif_carrier_on(dev); netdev_info(dev, "link up (%d/%s)\n", phydev->speed, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:498 @ static void macb_tx_unmap(struct macb *b static void macb_tx_error_task(struct work_struct *work) { - struct macb *bp = container_of(work, struct macb, tx_error_task); + struct macb_queue *queue = container_of(work, struct macb_queue, + tx_error_task); + struct macb *bp = queue->bp; struct macb_tx_skb *tx_skb; + struct macb_dma_desc *desc; struct sk_buff *skb; unsigned int tail; + unsigned long flags; - netdev_vdbg(bp->dev, "macb_tx_error_task: t = %u, h = %u\n", - bp->tx_tail, bp->tx_head); + netdev_vdbg(bp->dev, "macb_tx_error_task: q = %u, t = %u, h = %u\n", + (unsigned int)(queue - bp->queues), + queue->tx_tail, queue->tx_head); + + /* Prevent the queue IRQ handlers from running: each of them may call + * macb_tx_interrupt(), which in turn may call netif_wake_subqueue(). + * As explained below, we have to halt the transmission before updating + * TBQP registers so we call netif_tx_stop_all_queues() to notify the + * network engine about the macb/gem being halted. + */ + spin_lock_irqsave(&bp->lock, flags); /* Make sure nobody is trying to queue up new packets */ - netif_stop_queue(bp->dev); + netif_tx_stop_all_queues(bp->dev); /* * Stop transmission now * (in case we have just queued new packets) + * macb/gem must be halted to write TBQP register */ if (macb_halt_tx(bp)) /* Just complain for now, reinitializing TX path can be good */ netdev_err(bp->dev, "BUG: halt tx timed out\n"); - /* No need for the lock here as nobody will interrupt us anymore */ - /* * Treat frames in TX queue including the ones that caused the error. * Free transmit buffers in upper layer. */ - for (tail = bp->tx_tail; tail != bp->tx_head; tail++) { - struct macb_dma_desc *desc; - u32 ctrl; + for (tail = queue->tx_tail; tail != queue->tx_head; tail++) { + u32 ctrl; - desc = macb_tx_desc(bp, tail); + desc = macb_tx_desc(queue, tail); ctrl = desc->ctrl; - tx_skb = macb_tx_skb(bp, tail); + tx_skb = macb_tx_skb(queue, tail); skb = tx_skb->skb; if (ctrl & MACB_BIT(TX_USED)) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:548 @ static void macb_tx_error_task(struct wo while (!skb) { macb_tx_unmap(bp, tx_skb); tail++; - tx_skb = macb_tx_skb(bp, tail); + tx_skb = macb_tx_skb(queue, tail); skb = tx_skb->skb; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:577 @ static void macb_tx_error_task(struct wo macb_tx_unmap(bp, tx_skb); } + /* Set end of TX queue */ + desc = macb_tx_desc(queue, 0); + desc->addr = 0; + desc->ctrl = MACB_BIT(TX_USED); + /* Make descriptor updates visible to hardware */ wmb(); /* Reinitialize the TX desc queue */ - macb_writel(bp, TBQP, bp->tx_ring_dma); + queue_writel(queue, TBQP, queue->tx_ring_dma); /* Make TX ring reflect state of hardware */ - bp->tx_head = bp->tx_tail = 0; - - /* Now we are ready to start transmission again */ - netif_wake_queue(bp->dev); + queue->tx_head = 0; + queue->tx_tail = 0; /* Housework before enabling TX IRQ */ macb_writel(bp, TSR, macb_readl(bp, TSR)); - macb_writel(bp, IER, MACB_TX_INT_FLAGS); + queue_writel(queue, IER, MACB_TX_INT_FLAGS); + + /* Now we are ready to start transmission again */ + netif_tx_start_all_queues(bp->dev); + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); + + spin_unlock_irqrestore(&bp->lock, flags); } -static void macb_tx_interrupt(struct macb *bp) +static void macb_tx_interrupt(struct macb_queue *queue) { unsigned int tail; unsigned int head; u32 status; + struct macb *bp = queue->bp; + u16 queue_index = queue - bp->queues; status = macb_readl(bp, TSR); macb_writel(bp, TSR, status); if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - macb_writel(bp, ISR, MACB_BIT(TCOMP)); + queue_writel(queue, ISR, MACB_BIT(TCOMP)); netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", (unsigned long)status); - head = bp->tx_head; - for (tail = bp->tx_tail; tail != head; tail++) { + head = queue->tx_head; + for (tail = queue->tx_tail; tail != head; tail++) { struct macb_tx_skb *tx_skb; struct sk_buff *skb; struct macb_dma_desc *desc; u32 ctrl; - desc = macb_tx_desc(bp, tail); + desc = macb_tx_desc(queue, tail); /* Make hw descriptor updates visible to CPU */ rmb(); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:641 @ static void macb_tx_interrupt(struct mac /* Process all buffers of the current transmitted frame */ for (;; tail++) { - tx_skb = macb_tx_skb(bp, tail); + tx_skb = macb_tx_skb(queue, tail); skb = tx_skb->skb; /* First, update TX stats if needed */ @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:664 @ static void macb_tx_interrupt(struct mac } } - bp->tx_tail = tail; - if (netif_queue_stopped(bp->dev) - && CIRC_CNT(bp->tx_head, bp->tx_tail, - TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH) - netif_wake_queue(bp->dev); + queue->tx_tail = tail; + if (__netif_subqueue_stopped(bp->dev, queue_index) && + CIRC_CNT(queue->tx_head, queue->tx_tail, + TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH) + netif_wake_subqueue(bp->dev, queue_index); } static void gem_rx_refill(struct macb *bp) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:711 @ static void gem_rx_refill(struct macb *b /* properly align Ethernet header */ skb_reserve(skb, NET_IP_ALIGN); + } else { + bp->rx_ring[entry].addr &= ~MACB_BIT(RX_USED); + bp->rx_ring[entry].ctrl = 0; } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:809 @ static int gem_rx(struct macb *bp, int b netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n", skb->len, skb->csum); print_hex_dump(KERN_DEBUG, " mac: ", DUMP_PREFIX_ADDRESS, 16, 1, - skb->mac_header, 16, true); + skb_mac_header(skb), 16, true); print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_ADDRESS, 16, 1, skb->data, 32, true); #endif @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:982 @ static int macb_poll(struct napi_struct static irqreturn_t macb_interrupt(int irq, void *dev_id) { - struct net_device *dev = dev_id; - struct macb *bp = netdev_priv(dev); - u32 status; + struct macb_queue *queue = dev_id; + struct macb *bp = queue->bp; + struct net_device *dev = bp->dev; + u32 status, ctrl; - status = macb_readl(bp, ISR); + status = queue_readl(queue, ISR); if (unlikely(!status)) return IRQ_NONE; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:997 @ static irqreturn_t macb_interrupt(int ir while (status) { /* close possible race with dev_close */ if (unlikely(!netif_running(dev))) { - macb_writel(bp, IDR, -1); + queue_writel(queue, IDR, -1); break; } - netdev_vdbg(bp->dev, "isr = 0x%08lx\n", (unsigned long)status); + netdev_vdbg(bp->dev, "queue = %u, isr = 0x%08lx\n", + (unsigned int)(queue - bp->queues), + (unsigned long)status); if (status & MACB_RX_INT_FLAGS) { /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1013 @ static irqreturn_t macb_interrupt(int ir * is already scheduled, so disable interrupts * now. */ - macb_writel(bp, IDR, MACB_RX_INT_FLAGS); + queue_writel(queue, IDR, MACB_RX_INT_FLAGS); if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - macb_writel(bp, ISR, MACB_BIT(RCOMP)); + queue_writel(queue, ISR, MACB_BIT(RCOMP)); if (napi_schedule_prep(&bp->napi)) { netdev_vdbg(bp->dev, "scheduling RX softirq\n"); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1024 @ static irqreturn_t macb_interrupt(int ir } if (unlikely(status & (MACB_TX_ERR_FLAGS))) { - macb_writel(bp, IDR, MACB_TX_INT_FLAGS); - schedule_work(&bp->tx_error_task); + queue_writel(queue, IDR, MACB_TX_INT_FLAGS); + schedule_work(&queue->tx_error_task); if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - macb_writel(bp, ISR, MACB_TX_ERR_FLAGS); + queue_writel(queue, ISR, MACB_TX_ERR_FLAGS); break; } if (status & MACB_BIT(TCOMP)) - macb_tx_interrupt(bp); + macb_tx_interrupt(queue); /* * Link change detection isn't possible with RMII, so we'll * add that if/when we get our hands on a full-blown MII PHY. */ + /* There is a hardware issue under heavy load where DMA can + * stop, this causes endless "used buffer descriptor read" + * interrupts but it can be cleared by re-enabling RX. See + * the at91 manual, section 41.3.1 or the Zynq manual + * section 16.7.4 for details. + */ + if (status & MACB_BIT(RXUBR)) { + ctrl = macb_readl(bp, NCR); + macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); + macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); + + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + macb_writel(bp, ISR, MACB_BIT(RXUBR)); + } + if (status & MACB_BIT(ISR_ROVR)) { /* We missed at least one packet */ if (macb_is_gem(bp)) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1064 @ static irqreturn_t macb_interrupt(int ir bp->hw_stats.macb.rx_overruns++; if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - macb_writel(bp, ISR, MACB_BIT(ISR_ROVR)); + queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); } if (status & MACB_BIT(HRESP)) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1076 @ static irqreturn_t macb_interrupt(int ir netdev_err(dev, "DMA bus error: HRESP not OK\n"); if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - macb_writel(bp, ISR, MACB_BIT(HRESP)); + queue_writel(queue, ISR, MACB_BIT(HRESP)); } - status = macb_readl(bp, ISR); + status = queue_readl(queue, ISR); } spin_unlock(&bp->lock); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1094 @ static irqreturn_t macb_interrupt(int ir */ static void macb_poll_controller(struct net_device *dev) { + struct macb *bp = netdev_priv(dev); + struct macb_queue *queue; unsigned long flags; + unsigned int q; local_irq_save(flags); - macb_interrupt(dev->irq, dev); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + macb_interrupt(dev->irq, queue); local_irq_restore(flags); } #endif @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1113 @ static inline unsigned int macb_count_tx } static unsigned int macb_tx_map(struct macb *bp, + struct macb_queue *queue, struct sk_buff *skb) { dma_addr_t mapping; - unsigned int len, entry, i, tx_head = bp->tx_head; + unsigned int len, entry, i, tx_head = queue->tx_head; struct macb_tx_skb *tx_skb = NULL; struct macb_dma_desc *desc; unsigned int offset, size, count = 0; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1131 @ static unsigned int macb_tx_map(struct m while (len) { size = min(len, bp->max_tx_length); entry = macb_tx_ring_wrap(tx_head); - tx_skb = &bp->tx_skb[entry]; + tx_skb = &queue->tx_skb[entry]; mapping = dma_map_single(&bp->pdev->dev, skb->data + offset, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1160 @ static unsigned int macb_tx_map(struct m while (len) { size = min(len, bp->max_tx_length); entry = macb_tx_ring_wrap(tx_head); - tx_skb = &bp->tx_skb[entry]; + tx_skb = &queue->tx_skb[entry]; mapping = skb_frag_dma_map(&bp->pdev->dev, frag, offset, size, DMA_TO_DEVICE); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1199 @ static unsigned int macb_tx_map(struct m i = tx_head; entry = macb_tx_ring_wrap(i); ctrl = MACB_BIT(TX_USED); - desc = &bp->tx_ring[entry]; + desc = &queue->tx_ring[entry]; desc->ctrl = ctrl; do { i--; entry = macb_tx_ring_wrap(i); - tx_skb = &bp->tx_skb[entry]; - desc = &bp->tx_ring[entry]; + tx_skb = &queue->tx_skb[entry]; + desc = &queue->tx_ring[entry]; ctrl = (u32)tx_skb->size; if (eof) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1223 @ static unsigned int macb_tx_map(struct m */ wmb(); desc->ctrl = ctrl; - } while (i != bp->tx_head); + } while (i != queue->tx_head); - bp->tx_head = tx_head; + queue->tx_head = tx_head; return count; dma_error: netdev_err(bp->dev, "TX DMA map failed\n"); - for (i = bp->tx_head; i != tx_head; i++) { - tx_skb = macb_tx_skb(bp, i); + for (i = queue->tx_head; i != tx_head; i++) { + tx_skb = macb_tx_skb(queue, i); macb_tx_unmap(bp, tx_skb); } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1243 @ dma_error: static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) { + u16 queue_index = skb_get_queue_mapping(skb); struct macb *bp = netdev_priv(dev); + struct macb_queue *queue = &bp->queues[queue_index]; unsigned long flags; unsigned int count, nr_frags, frag_size, f; #if defined(DEBUG) && defined(VERBOSE_DEBUG) netdev_vdbg(bp->dev, - "start_xmit: len %u head %p data %p tail %p end %p\n", - skb->len, skb->head, skb->data, + "start_xmit: queue %hu len %u head %p data %p tail %p end %p\n", + queue_index, skb->len, skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb)); print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1, skb->data, 16, true); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1272 @ static int macb_start_xmit(struct sk_buf spin_lock_irqsave(&bp->lock, flags); /* This is a hard error, log it. */ - if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < count) { - netif_stop_queue(dev); + if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < count) { + netif_stop_subqueue(dev, queue_index); spin_unlock_irqrestore(&bp->lock, flags); netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n", - bp->tx_head, bp->tx_tail); + queue->tx_head, queue->tx_tail); return NETDEV_TX_BUSY; } /* Map socket buffer for DMA transfer */ - if (!macb_tx_map(bp, skb)) { + if (!macb_tx_map(bp, queue, skb)) { dev_kfree_skb_any(skb); goto unlock; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1293 @ static int macb_start_xmit(struct sk_buf macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); - if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) - netif_stop_queue(dev); + if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < 1) + netif_stop_subqueue(dev, queue_index); unlock: spin_unlock_irqrestore(&bp->lock, flags); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1362 @ static void macb_free_rx_buffers(struct static void macb_free_consistent(struct macb *bp) { - if (bp->tx_skb) { - kfree(bp->tx_skb); - bp->tx_skb = NULL; - } + struct macb_queue *queue; + unsigned int q; + bp->macbgem_ops.mog_free_rx_buffers(bp); if (bp->rx_ring) { dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES, bp->rx_ring, bp->rx_ring_dma); bp->rx_ring = NULL; } - if (bp->tx_ring) { - dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES, - bp->tx_ring, bp->tx_ring_dma); - bp->tx_ring = NULL; + + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + kfree(queue->tx_skb); + queue->tx_skb = NULL; + if (queue->tx_ring) { + dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES, + queue->tx_ring, queue->tx_ring_dma); + queue->tx_ring = NULL; + } } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1416 @ static int macb_alloc_rx_buffers(struct static int macb_alloc_consistent(struct macb *bp) { + struct macb_queue *queue; + unsigned int q; int size; - size = TX_RING_SIZE * sizeof(struct macb_tx_skb); - bp->tx_skb = kmalloc(size, GFP_KERNEL); - if (!bp->tx_skb) - goto out_err; + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + size = TX_RING_BYTES; + queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, + &queue->tx_ring_dma, + GFP_KERNEL); + if (!queue->tx_ring) + goto out_err; + netdev_dbg(bp->dev, + "Allocated TX ring for queue %u of %d bytes at %08lx (mapped %p)\n", + q, size, (unsigned long)queue->tx_ring_dma, + queue->tx_ring); + + size = TX_RING_SIZE * sizeof(struct macb_tx_skb); + queue->tx_skb = kmalloc(size, GFP_KERNEL); + if (!queue->tx_skb) + goto out_err; + } size = RX_RING_BYTES; bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1447 @ static int macb_alloc_consistent(struct "Allocated RX ring of %d bytes at %08lx (mapped %p)\n", size, (unsigned long)bp->rx_ring_dma, bp->rx_ring); - size = TX_RING_BYTES; - bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, - &bp->tx_ring_dma, GFP_KERNEL); - if (!bp->tx_ring) - goto out_err; - netdev_dbg(bp->dev, - "Allocated TX ring of %d bytes at %08lx (mapped %p)\n", - size, (unsigned long)bp->tx_ring_dma, bp->tx_ring); - if (bp->macbgem_ops.mog_alloc_rx_buffers(bp)) goto out_err; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1459 @ out_err: static void gem_init_rings(struct macb *bp) { + struct macb_queue *queue; + unsigned int q; int i; - for (i = 0; i < TX_RING_SIZE; i++) { - bp->tx_ring[i].addr = 0; - bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + for (i = 0; i < TX_RING_SIZE; i++) { + queue->tx_ring[i].addr = 0; + queue->tx_ring[i].ctrl = MACB_BIT(TX_USED); + } + queue->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); + queue->tx_head = 0; + queue->tx_tail = 0; } - bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); - bp->rx_tail = bp->rx_prepared_head = bp->tx_head = bp->tx_tail = 0; + bp->rx_tail = 0; + bp->rx_prepared_head = 0; gem_rx_refill(bp); } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1493 @ static void macb_init_rings(struct macb bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP); for (i = 0; i < TX_RING_SIZE; i++) { - bp->tx_ring[i].addr = 0; - bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); + bp->queues[0].tx_ring[i].addr = 0; + bp->queues[0].tx_ring[i].ctrl = MACB_BIT(TX_USED); } - bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); + bp->queues[0].tx_head = 0; + bp->queues[0].tx_tail = 0; + bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); - bp->rx_tail = bp->tx_head = bp->tx_tail = 0; + bp->rx_tail = 0; } static void macb_reset_hw(struct macb *bp) { + struct macb_queue *queue; + unsigned int q; + /* * Disable RX and TX (XXX: Should we halt the transmission * more gracefully?) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1522 @ static void macb_reset_hw(struct macb *b macb_writel(bp, RSR, -1); /* Disable all interrupts */ - macb_writel(bp, IDR, -1); - macb_readl(bp, ISR); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + queue_writel(queue, IDR, -1); + queue_readl(queue, ISR); + } } static u32 gem_mdc_clk_div(struct macb *bp) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1622 @ static void macb_configure_dma(struct ma static void macb_init_hw(struct macb *bp) { + struct macb_queue *queue; + unsigned int q; + u32 config; macb_reset_hw(bp); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1650 @ static void macb_init_hw(struct macb *bp /* Initialize TX and RX buffers */ macb_writel(bp, RBQP, bp->rx_ring_dma); - macb_writel(bp, TBQP, bp->tx_ring_dma); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + queue_writel(queue, TBQP, queue->tx_ring_dma); + + /* Enable interrupts */ + queue_writel(queue, IER, + MACB_RX_INT_FLAGS | + MACB_TX_INT_FLAGS | + MACB_BIT(HRESP)); + } /* Enable TX and RX */ macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE)); - - /* Enable interrupts */ - macb_writel(bp, IER, (MACB_RX_INT_FLAGS - | MACB_TX_INT_FLAGS - | MACB_BIT(HRESP))); - } /* @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1823 @ static int macb_open(struct net_device * /* schedule a link state check */ phy_start(bp->phy_dev); - netif_start_queue(dev); + netif_tx_start_all_queues(dev); return 0; } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1833 @ static int macb_close(struct net_device struct macb *bp = netdev_priv(dev); unsigned long flags; - netif_stop_queue(dev); + netif_tx_stop_all_queues(dev); napi_disable(&bp->napi); if (bp->phy_dev) @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1917 @ struct net_device_stats *macb_get_stats( hwstat->rx_oversize_pkts + hwstat->rx_jabbers + hwstat->rx_undersize_pkts + - hwstat->sqe_test_errors + hwstat->rx_length_mismatch); nstat->tx_errors = (hwstat->tx_late_cols + hwstat->tx_excessive_cols + hwstat->tx_underruns + - hwstat->tx_carrier_errors); + hwstat->tx_carrier_errors + + hwstat->sqe_test_errors); nstat->collisions = (hwstat->tx_single_cols + hwstat->tx_multiple_cols + hwstat->tx_excessive_cols); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1982 @ static void macb_get_regs(struct net_dev regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1)) | MACB_GREGS_VERSION; - tail = macb_tx_ring_wrap(bp->tx_tail); - head = macb_tx_ring_wrap(bp->tx_head); + tail = macb_tx_ring_wrap(bp->queues[0].tx_tail); + head = macb_tx_ring_wrap(bp->queues[0].tx_head); regs_buff[0] = macb_readl(bp, NCR); regs_buff[1] = macb_or_gem_readl(bp, NCFGR); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1996 @ static void macb_get_regs(struct net_dev regs_buff[8] = tail; regs_buff[9] = head; - regs_buff[10] = macb_tx_dma(bp, tail); - regs_buff[11] = macb_tx_dma(bp, head); + regs_buff[10] = macb_tx_dma(&bp->queues[0], tail); + regs_buff[11] = macb_tx_dma(&bp->queues[0], head); + regs_buff[12] = macb_or_gem_readl(bp, USRIO); if (macb_is_gem(bp)) { - regs_buff[12] = gem_readl(bp, USRIO); regs_buff[13] = gem_readl(bp, DMACFG); } } @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2148 @ static void macb_configure_caps(struct m netdev_dbg(bp->dev, "Cadence caps 0x%08x\n", bp->caps); } +static void macb_probe_queues(void __iomem *mem, + unsigned int *queue_mask, + unsigned int *num_queues) +{ + unsigned int hw_q; + u32 mid; + + *queue_mask = 0x1; + *num_queues = 1; + + /* is it macb or gem ? */ + mid = __raw_readl(mem + MACB_MID); + if (MACB_BFEXT(IDNUM, mid) != 0x2) + return; + + /* bit 0 is never set but queue 0 always exists */ + *queue_mask = __raw_readl(mem + GEM_DCFG6) & 0xff; + *queue_mask |= 0x1; + + for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q) + if (*queue_mask & (1 << hw_q)) + (*num_queues)++; +} + static int __init macb_probe(struct platform_device *pdev) { struct macb_platform_data *pdata; struct resource *regs; struct net_device *dev; struct macb *bp; + struct macb_queue *queue; struct phy_device *phydev; u32 config; int err = -ENXIO; const char *mac; + void __iomem *mem; + unsigned int hw_q, queue_mask, q, num_queues; + struct clk *pclk, *hclk, *tx_clk; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2193 @ static int __init macb_probe(struct plat goto err_out; } - err = -ENOMEM; - dev = alloc_etherdev(sizeof(*bp)); - if (!dev) - goto err_out; - - SET_NETDEV_DEV(dev, &pdev->dev); - - bp = netdev_priv(dev); - bp->pdev = pdev; - bp->dev = dev; - - spin_lock_init(&bp->lock); - INIT_WORK(&bp->tx_error_task, macb_tx_error_task); - - bp->pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(bp->pclk)) { - err = PTR_ERR(bp->pclk); + pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(pclk)) { + err = PTR_ERR(pclk); dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); - goto err_out_free_dev; + goto err_out; } - bp->hclk = devm_clk_get(&pdev->dev, "hclk"); - if (IS_ERR(bp->hclk)) { - err = PTR_ERR(bp->hclk); + hclk = devm_clk_get(&pdev->dev, "hclk"); + if (IS_ERR(hclk)) { + err = PTR_ERR(hclk); dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); - goto err_out_free_dev; + goto err_out; } - bp->tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); + tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); - err = clk_prepare_enable(bp->pclk); + err = clk_prepare_enable(pclk); if (err) { dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); - goto err_out_free_dev; + goto err_out; } - err = clk_prepare_enable(bp->hclk); + err = clk_prepare_enable(hclk); if (err) { dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err); goto err_out_disable_pclk; } - if (!IS_ERR(bp->tx_clk)) { - err = clk_prepare_enable(bp->tx_clk); + if (!IS_ERR(tx_clk)) { + err = clk_prepare_enable(tx_clk); if (err) { dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", - err); + err); goto err_out_disable_hclk; } } - bp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); - if (!bp->regs) { + err = -ENOMEM; + mem = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); + if (!mem) { dev_err(&pdev->dev, "failed to map registers, aborting.\n"); - err = -ENOMEM; goto err_out_disable_clocks; } - dev->irq = platform_get_irq(pdev, 0); - err = devm_request_irq(&pdev->dev, dev->irq, macb_interrupt, 0, - dev->name, dev); - if (err) { - dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", - dev->irq, err); + macb_probe_queues(mem, &queue_mask, &num_queues); + dev = alloc_etherdev_mq(sizeof(*bp), num_queues); + if (!dev) goto err_out_disable_clocks; + + SET_NETDEV_DEV(dev, &pdev->dev); + + bp = netdev_priv(dev); + bp->pdev = pdev; + bp->dev = dev; + bp->regs = mem; + bp->num_queues = num_queues; + bp->pclk = pclk; + bp->hclk = hclk; + bp->tx_clk = tx_clk; + + spin_lock_init(&bp->lock); + + /* set the queue register mapping once for all: queue0 has a special + * register mapping but we don't want to test the queue index then + * compute the corresponding register offset at run time. + */ + for (hw_q = 0, q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) { + if (!(queue_mask & (1 << hw_q))) + continue; + + queue = &bp->queues[q]; + queue->bp = bp; + if (hw_q) { + queue->ISR = GEM_ISR(hw_q - 1); + queue->IER = GEM_IER(hw_q - 1); + queue->IDR = GEM_IDR(hw_q - 1); + queue->IMR = GEM_IMR(hw_q - 1); + queue->TBQP = GEM_TBQP(hw_q - 1); + } else { + /* queue0 uses legacy registers */ + queue->ISR = MACB_ISR; + queue->IER = MACB_IER; + queue->IDR = MACB_IDR; + queue->IMR = MACB_IMR; + queue->TBQP = MACB_TBQP; + } + + /* get irq: here we use the linux queue index, not the hardware + * queue index. the queue irq definitions in the device tree + * must remove the optional gaps that could exist in the + * hardware queue mask. + */ + queue->irq = platform_get_irq(pdev, q); + err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt, + 0, dev->name, queue); + if (err) { + dev_err(&pdev->dev, + "Unable to request IRQ %d (error %d)\n", + queue->irq, err); + goto err_out_free_netdev; + } + + INIT_WORK(&queue->tx_error_task, macb_tx_error_task); + q++; } + dev->irq = bp->queues[0].irq; dev->netdev_ops = &macb_netdev_ops; netif_napi_add(dev, &bp->napi, macb_poll, 64); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2374 @ static int __init macb_probe(struct plat err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); - goto err_out_disable_clocks; + goto err_out_free_netdev; } err = macb_mii_init(bp); @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2397 @ static int __init macb_probe(struct plat err_out_unregister_netdev: unregister_netdev(dev); +err_out_free_netdev: + free_netdev(dev); err_out_disable_clocks: - if (!IS_ERR(bp->tx_clk)) - clk_disable_unprepare(bp->tx_clk); + if (!IS_ERR(tx_clk)) + clk_disable_unprepare(tx_clk); err_out_disable_hclk: - clk_disable_unprepare(bp->hclk); + clk_disable_unprepare(hclk); err_out_disable_pclk: - clk_disable_unprepare(bp->pclk); -err_out_free_dev: - free_netdev(dev); + clk_disable_unprepare(pclk); err_out: return err; } Index: linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/macb.h =================================================================== --- linux-3.18.13-rt10-r7s4.orig/drivers/net/ethernet/cadence/macb.h +++ linux-3.18.13-rt10-r7s4/drivers/net/ethernet/cadence/macb.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:14 @ #define _MACB_H #define MACB_GREGS_NBR 16 -#define MACB_GREGS_VERSION 1 +#define MACB_GREGS_VERSION 2 +#define MACB_MAX_QUEUES 8 /* MACB register offsets */ #define MACB_NCR 0x0000 @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:93 @ #define GEM_DCFG6 0x0294 #define GEM_DCFG7 0x0298 +#define GEM_ISR(hw_q) (0x0400 + ((hw_q) << 2)) +#define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2)) +#define GEM_RBQP(hw_q) (0x0480 + ((hw_q) << 2)) +#define GEM_IER(hw_q) (0x0600 + ((hw_q) << 2)) +#define GEM_IDR(hw_q) (0x0620 + ((hw_q) << 2)) +#define GEM_IMR(hw_q) (0x0640 + ((hw_q) << 2)) + /* Bitfields in NCR */ #define MACB_LB_OFFSET 0 #define MACB_LB_SIZE 1 @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:387 @ __raw_readl((port)->regs + GEM_##reg) #define gem_writel(port, reg, value) \ __raw_writel((value), (port)->regs + GEM_##reg) +#define queue_readl(queue, reg) \ + __raw_readl((queue)->bp->regs + (queue)->reg) +#define queue_writel(queue, reg, value) \ + __raw_writel((value), (queue)->bp->regs + (queue)->reg) /* * Conditional GEM/MACB macros. These perform the operation to the correct @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:612 @ struct macb_config { unsigned int dma_burst_length; }; +struct macb_queue { + struct macb *bp; + int irq; + + unsigned int ISR; + unsigned int IER; + unsigned int IDR; + unsigned int IMR; + unsigned int TBQP; + + unsigned int tx_head, tx_tail; + struct macb_dma_desc *tx_ring; + struct macb_tx_skb *tx_skb; + dma_addr_t tx_ring_dma; + struct work_struct tx_error_task; +}; + struct macb { void __iomem *regs; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:639 @ struct macb { void *rx_buffers; size_t rx_buffer_size; - unsigned int tx_head, tx_tail; - struct macb_dma_desc *tx_ring; - struct macb_tx_skb *tx_skb; + unsigned int num_queues; + struct macb_queue queues[MACB_MAX_QUEUES]; spinlock_t lock; struct platform_device *pdev; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:649 @ struct macb { struct clk *tx_clk; struct net_device *dev; struct napi_struct napi; - struct work_struct tx_error_task; struct net_device_stats stats; union { struct macb_stats macb; @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:656 @ struct macb { } hw_stats; dma_addr_t rx_ring_dma; - dma_addr_t tx_ring_dma; dma_addr_t rx_buffers_dma; struct macb_or_gem_ops macbgem_ops; Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/Kconfig =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +menuconfig ATMEL_SMARTCONNECT + bool "Atmel SmartConnect wireless cards Driver" + depends on WLAN && CFG80211 +# select WIRELESS_EXT +# select WEXT_PRIV + ---help--- + This module adds support for wireless adapters based on + Atmel chipsets. + +if ATMEL_SMARTCONNECT + +source "drivers/net/wireless/atmel/wilc1000/Kconfig" + +endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/Makefile =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:1 @ +obj-$(CONFIG_ATMEL_SMARTCONNECT) += wilc1000/ Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigsimulator.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigsimulator.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +/*! + * @file coreconfigsimulator.h + * @brief + * @author + * @sa coreconfigsimulator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGSIMULATOR_H +#define CORECONFIGSIMULATOR_H + + +extern WILC_Sint32 CoreConfigSimulatorInit (void); +extern WILC_Sint32 CoreConfigSimulatorDeInit (void); + + +#endif \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigurator.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigurator.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +/*! + * @file coreconfigurator.c + * @brief + * @author + * @sa coreconfigurator.h + * @date 1 Mar 2012 + * @version 1.0 + */ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include "itypes.h" +#include "coreconfigurator.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +#define INLINE static __inline +#define PHY_802_11n +#define MAX_CFG_PKTLEN 1450 +#define MSG_HEADER_LEN 4 +#define QUERY_MSG_TYPE 'Q' +#define WRITE_MSG_TYPE 'W' +#define RESP_MSG_TYPE 'R' +#define WRITE_RESP_SUCCESS 1 +#define INVALID 255 +#define MAC_ADDR_LEN 6 +#define TAG_PARAM_OFFSET (MAC_HDR_LEN + TIME_STAMP_LEN + \ + BEACON_INTERVAL_LEN + CAP_INFO_LEN) + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/* Basic Frame Type Codes (2-bit) */ +typedef enum {FRAME_TYPE_CONTROL = 0x04, + FRAME_TYPE_DATA = 0x08, + FRAME_TYPE_MANAGEMENT = 0x00, + FRAME_TYPE_RESERVED = 0x0C, + FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuBasicFrmType; + +/* Frame Type and Subtype Codes (6-bit) */ +typedef enum { + ASSOC_REQ = 0x00, + ASSOC_RSP = 0x10, + REASSOC_REQ = 0x20, + REASSOC_RSP = 0x30, + PROBE_REQ = 0x40, + PROBE_RSP = 0x50, + BEACON = 0x80, + ATIM = 0x90, + DISASOC = 0xA0, + AUTH = 0xB0, + DEAUTH = 0xC0, + ACTION = 0xD0, + PS_POLL = 0xA4, + RTS = 0xB4, + CTS = 0xC4, + ACK = 0xD4, + CFEND = 0xE4, + CFEND_ACK = 0xF4, + DATA = 0x08, + DATA_ACK = 0x18, + DATA_POLL = 0x28, + DATA_POLL_ACK = 0x38, + NULL_FRAME = 0x48, + CFACK = 0x58, + CFPOLL = 0x68, + CFPOLL_ACK = 0x78, + QOS_DATA = 0x88, + QOS_DATA_ACK = 0x98, + QOS_DATA_POLL = 0xA8, + QOS_DATA_POLL_ACK = 0xB8, + QOS_NULL_FRAME = 0xC8, + QOS_CFPOLL = 0xE8, + QOS_CFPOLL_ACK = 0xF8, + BLOCKACK_REQ = 0x84, + BLOCKACK = 0x94, + FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuFrmSubtype; + +/* Basic Frame Classes */ +typedef enum { + CLASS1_FRAME_TYPE = 0x00, + CLASS2_FRAME_TYPE = 0x01, + CLASS3_FRAME_TYPE = 0x02, + FRAME_CLASS_FORCE_32BIT = 0xFFFFFFFF +} tenuFrameClass; + +/* Element ID of various Information Elements */ +typedef enum { + ISSID = 0, /* Service Set Identifier */ + ISUPRATES = 1, /* Supported Rates */ + IFHPARMS = 2, /* FH parameter set */ + IDSPARMS = 3, /* DS parameter set */ + ICFPARMS = 4, /* CF parameter set */ + ITIM = 5, /* Traffic Information Map */ + IIBPARMS = 6, /* IBSS parameter set */ + ICOUNTRY = 7, /* Country element */ + IEDCAPARAMS = 12, /* EDCA parameter set */ + ITSPEC = 13, /* Traffic Specification */ + ITCLAS = 14, /* Traffic Classification */ + ISCHED = 15, /* Schedule */ + ICTEXT = 16, /* Challenge Text */ + IPOWERCONSTRAINT = 32, /* Power Constraint */ + IPOWERCAPABILITY = 33, /* Power Capability */ + ITPCREQUEST = 34, /* TPC Request */ + ITPCREPORT = 35, /* TPC Report */ + ISUPCHANNEL = 36, /* Supported channel list */ + ICHSWANNOUNC = 37, /* Channel Switch Announcement */ + IMEASUREMENTREQUEST = 38, /* Measurement request */ + IMEASUREMENTREPORT = 39, /* Measurement report */ + IQUIET = 40, /* Quiet element Info */ + IIBSSDFS = 41, /* IBSS DFS */ + IERPINFO = 42, /* ERP Information */ + ITSDELAY = 43, /* TS Delay */ + ITCLASPROCESS = 44, /* TCLAS Processing */ + IHTCAP = 45, /* HT Capabilities */ + IQOSCAP = 46, /* QoS Capability */ + IRSNELEMENT = 48, /* RSN Information Element */ + IEXSUPRATES = 50, /* Extended Supported Rates */ + IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/ + IHTOPERATION = 61, /* HT Information */ + ISECCHOFF = 62, /* Secondary Channel Offeset */ + I2040COEX = 72, /* 20/40 Coexistence IE */ + I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/ + IOBSSSCAN = 74, /* OBSS Scan parameters */ + IEXTCAP = 127, /* Extended capability */ + IWMM = 221, /* WMM parameters */ + IWPAELEMENT = 221, /* WPA Information Element */ + INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF +} tenuInfoElemID; + + +typedef struct { + WILC_Char *pcRespBuffer; + WILC_Sint32 s32MaxRespBuffLen; + WILC_Sint32 s32BytesRead; + WILC_Bool bRespRequired; +} tstrConfigPktInfo; + + + +/*****************************************************************************/ +/* Extern Variable Declarations */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Extern Function Declarations */ +/*****************************************************************************/ +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *ps8Packet, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +extern void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +extern void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +/*****************************************************************************/ +/* Global Variables */ +/*****************************************************************************/ +static WILC_SemaphoreHandle SemHandleSendPkt; +static WILC_SemaphoreHandle SemHandlePktResp; + +static WILC_Sint8 *gps8ConfigPacket; + +static tstrConfigPktInfo gstrConfigPktInfo; + +static WILC_Uint8 g_seqno; + +static WILC_Sint16 g_wid_num = -1; + +static WILC_Uint16 Res_Len; + +static WILC_Uint8 g_oper_mode = SET_CFG; + +/* WID Switches */ +static tstrWID gastrWIDs[] = { + {WID_FIRMWARE_VERSION, WID_STR}, + {WID_PHY_VERSION, WID_STR}, + {WID_HARDWARE_VERSION, WID_STR}, + {WID_BSS_TYPE, WID_CHAR}, + {WID_QOS_ENABLE, WID_CHAR}, + {WID_11I_MODE, WID_CHAR}, + {WID_CURRENT_TX_RATE, WID_CHAR}, + {WID_LINKSPEED, WID_CHAR}, + {WID_RTS_THRESHOLD, WID_SHORT}, + {WID_FRAG_THRESHOLD, WID_SHORT}, + {WID_SSID, WID_STR}, + {WID_BSSID, WID_ADR}, + {WID_BEACON_INTERVAL, WID_SHORT}, + {WID_POWER_MANAGEMENT, WID_CHAR}, + {WID_LISTEN_INTERVAL, WID_CHAR}, + {WID_DTIM_PERIOD, WID_CHAR}, + {WID_CURRENT_CHANNEL, WID_CHAR}, + {WID_TX_POWER_LEVEL_11A, WID_CHAR}, + {WID_TX_POWER_LEVEL_11B, WID_CHAR}, + {WID_PREAMBLE, WID_CHAR}, + {WID_11G_OPERATING_MODE, WID_CHAR}, + {WID_MAC_ADDR, WID_ADR}, + {WID_IP_ADDRESS, WID_ADR}, + {WID_ACK_POLICY, WID_CHAR}, + {WID_PHY_ACTIVE_REG, WID_CHAR}, + {WID_AUTH_TYPE, WID_CHAR}, + {WID_REKEY_POLICY, WID_CHAR}, + {WID_REKEY_PERIOD, WID_INT}, + {WID_REKEY_PACKET_COUNT, WID_INT}, +#if 0 + {WID_WEP_KEY_VALUE0, WID_STR}, +#endif + {WID_11I_PSK, WID_STR}, + {WID_1X_KEY, WID_STR}, + {WID_1X_SERV_ADDR, WID_IP}, + {WID_SUPP_USERNAME, WID_STR}, + {WID_SUPP_PASSWORD, WID_STR}, + {WID_USER_CONTROL_ON_TX_POWER, WID_CHAR}, + {WID_MEMORY_ADDRESS, WID_INT}, + {WID_MEMORY_ACCESS_32BIT, WID_INT}, + {WID_MEMORY_ACCESS_16BIT, WID_SHORT}, + {WID_MEMORY_ACCESS_8BIT, WID_CHAR}, + {WID_SITE_SURVEY_RESULTS, WID_STR}, + {WID_PMKID_INFO, WID_STR}, + {WID_ASSOC_RES_INFO, WID_STR}, + {WID_MANUFACTURER, WID_STR}, /* 4 Wids added for the CAPI tool*/ + {WID_MODEL_NAME, WID_STR}, + {WID_MODEL_NUM, WID_STR}, + {WID_DEVICE_NAME, WID_STR}, + {WID_SSID_PROBE_REQ, WID_STR}, + +#ifdef MAC_802_11N + {WID_11N_ENABLE, WID_CHAR}, + {WID_11N_CURRENT_TX_MCS, WID_CHAR}, + {WID_TX_POWER_LEVEL_11N, WID_CHAR}, + {WID_11N_OPERATING_MODE, WID_CHAR}, + {WID_11N_SMPS_MODE, WID_CHAR}, + {WID_11N_PROT_MECH, WID_CHAR}, + {WID_11N_ERP_PROT_TYPE, WID_CHAR}, + {WID_11N_HT_PROT_TYPE, WID_CHAR}, + {WID_11N_PHY_ACTIVE_REG_VAL, WID_INT}, + {WID_11N_PRINT_STATS, WID_CHAR}, + {WID_11N_AUTORATE_TABLE, WID_BIN_DATA}, + {WID_HOST_CONFIG_IF_TYPE, WID_CHAR}, + {WID_HOST_DATA_IF_TYPE, WID_CHAR}, + {WID_11N_SIG_QUAL_VAL, WID_SHORT}, + {WID_11N_IMMEDIATE_BA_ENABLED, WID_CHAR}, + {WID_11N_TXOP_PROT_DISABLE, WID_CHAR}, + {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR}, + {WID_SHORT_SLOT_ALLOWED, WID_CHAR}, + {WID_11W_ENABLE, WID_CHAR}, + {WID_11W_MGMT_PROT_REQ, WID_CHAR}, + {WID_2040_ENABLE, WID_CHAR}, + {WID_2040_COEXISTENCE, WID_CHAR}, + {WID_USER_SEC_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_CURR_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_40MHZ_INTOLERANT, WID_CHAR}, + {WID_HUT_RESTART, WID_CHAR}, + {WID_HUT_NUM_TX_PKTS, WID_INT}, + {WID_HUT_FRAME_LEN, WID_SHORT}, + {WID_HUT_TX_FORMAT, WID_CHAR}, + {WID_HUT_BANDWIDTH, WID_CHAR}, + {WID_HUT_OP_BAND, WID_CHAR}, + {WID_HUT_STBC, WID_CHAR}, + {WID_HUT_ESS, WID_CHAR}, + {WID_HUT_ANTSET, WID_CHAR}, + {WID_HUT_HT_OP_MODE, WID_CHAR}, + {WID_HUT_RIFS_MODE, WID_CHAR}, + {WID_HUT_SMOOTHING_REC, WID_CHAR}, + {WID_HUT_SOUNDING_PKT, WID_CHAR}, + {WID_HUT_HT_CODING, WID_CHAR}, + {WID_HUT_TEST_DIR, WID_CHAR}, + {WID_HUT_TXOP_LIMIT, WID_SHORT}, + {WID_HUT_DEST_ADDR, WID_ADR}, + {WID_HUT_TX_PATTERN, WID_BIN_DATA}, + {WID_HUT_TX_TIME_TAKEN, WID_INT}, + {WID_HUT_PHY_TEST_MODE, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_HI, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_LO, WID_CHAR}, + {WID_HUT_TX_TEST_TIME, WID_INT}, + {WID_HUT_LOG_INTERVAL, WID_INT}, + {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR}, + {WID_HUT_TEST_ID, WID_STR}, + {WID_HUT_KEY_ORIGIN, WID_CHAR}, + {WID_HUT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_GROUP_CIPHER_TYPE, WID_CHAR}, + {WID_HUT_STATS, WID_BIN_DATA}, + {WID_HUT_TSF_TEST_MODE, WID_CHAR}, + {WID_HUT_SIG_QUAL_AVG, WID_SHORT}, + {WID_HUT_SIG_QUAL_AVG_CNT, WID_SHORT}, + {WID_HUT_TSSI_VALUE, WID_CHAR}, + {WID_HUT_MGMT_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_ALLOW_HT, WID_CHAR}, + {WID_HUT_UC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_BC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_UC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_BC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_11W_MFP_REQUIRED_TX, WID_CHAR}, + {WID_HUT_11W_MFP_PEER_CAPABLE, WID_CHAR}, + {WID_HUT_11W_TX_IGTK_ID, WID_CHAR}, + {WID_HUT_FC_TXOP_MOD, WID_CHAR}, + {WID_HUT_FC_PROT_TYPE, WID_CHAR}, + {WID_HUT_SEC_CCA_ASSERT, WID_CHAR}, +#endif /* MAC_802_11N */ +}; + +WILC_Uint16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID)); +/*****************************************************************************/ +/* Static Function Declarations */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ +INLINE WILC_Uint8 ascii_hex_to_dec(WILC_Uint8 num) +{ + if ((num >= '0') && (num <= '9')) + return (num - '0'); + else if ((num >= 'A') && (num <= 'F')) + return (10 + (num - 'A')); + else if ((num >= 'a') && (num <= 'f')) + return (10 + (num - 'a')); + + return INVALID; +} + +INLINE WILC_Uint8 get_hex_char(WILC_Uint8 inp) +{ + WILC_Uint8 *d2htab = "0123456789ABCDEF"; + + return d2htab[inp & 0xF]; +} + +/* This function extracts the MAC address held in a string in standard format */ +/* into another buffer as integers. */ +INLINE WILC_Uint16 extract_mac_addr(WILC_Char *str, WILC_Uint8 *buff) +{ + *buff = 0; + while (*str != '\0') { + if ((*str == ':') || (*str == '-')) + *(++buff) = 0; + else + *buff = (*buff << 4) + ascii_hex_to_dec(*str); + + str++; + } + + return MAC_ADDR_LEN; +} + +/* This function creates MAC address in standard format from a buffer of */ +/* integers. */ +INLINE void create_mac_addr(WILC_Uint8 *str, WILC_Uint8 *buff) +{ + WILC_Uint32 i = 0; + WILC_Uint32 j = 0; + + for (i = 0; i < MAC_ADDR_LEN; i++) { + str[j++] = get_hex_char((WILC_Uint8)((buff[i] >> 4) & 0x0F)); + str[j++] = get_hex_char((WILC_Uint8)(buff[i] & 0x0F)); + str[j++] = ':'; + } + str[--j] = '\0'; +} + +/* This function converts the IP address string in dotted decimal format to */ +/* unsigned integer. This functionality is similar to the library function */ +/* inet_addr() but is reimplemented here since I could not confirm that */ +/* inet_addr is platform independent. */ +/* ips=>IP Address String in dotted decimal format */ +/* ipn=>Pointer to IP Address in integer format */ +INLINE WILC_Uint8 conv_ip_to_int(WILC_Uint8 *ips, WILC_Uint32 *ipn) +{ + WILC_Uint8 i = 0; + WILC_Uint8 ipb = 0; + *ipn = 0; + /* Integer to string for each component */ + while (ips[i] != '\0') { + if (ips[i] == '.') { + *ipn = ((*ipn) << 8) | ipb; + ipb = 0; + } else { + ipb = ipb * 10 + ascii_hex_to_dec(ips[i]); + } + + i++; + } + + /* The last byte of the IP address is read in here */ + *ipn = ((*ipn) << 8) | ipb; + + return 0; +} + +/* This function converts the IP address from integer format to dotted */ +/* decimal string format. Alternative to std library fn inet_ntoa(). */ +/* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B) */ +/* ipn=>IP Address in integer format */ +INLINE WILC_Uint8 conv_int_to_ip(WILC_Uint8 *ips, WILC_Uint32 ipn) +{ + WILC_Uint8 i = 0; + WILC_Uint8 ipb = 0; + WILC_Uint8 cnt = 0; + WILC_Uint8 ipbsize = 0; + + for (cnt = 4; cnt > 0; cnt--) { + ipb = (ipn >> (8 * (cnt - 1))) & 0xFF; + + if (ipb >= 100) + ipbsize = 2; + else if (ipb >= 10) + ipbsize = 1; + else + ipbsize = 0; + + switch (ipbsize) { + case 2: + ips[i++] = get_hex_char(ipb / 100); + ipb %= 100; + + case 1: + ips[i++] = get_hex_char(ipb / 10); + ipb %= 10; + + default: + ips[i++] = get_hex_char(ipb); + } + + if (cnt > 1) + ips[i++] = '.'; + } + + ips[i] = '\0'; + + return i; +} + +INLINE tenuWIDtype get_wid_type(WILC_Uint32 wid_num) +{ + /* Check for iconfig specific WID types first */ + if ((wid_num == WID_BSSID) || + (wid_num == WID_MAC_ADDR) || + (wid_num == WID_IP_ADDRESS) || + (wid_num == WID_HUT_DEST_ADDR)) { + return WID_ADR; + } + + if ((WID_1X_SERV_ADDR == wid_num) || + (WID_STACK_IP_ADDR == wid_num) || + (WID_STACK_NETMASK_ADDR == wid_num)) { + return WID_IP; + } + + /* Next check for standard WID types */ + if (wid_num < 0x1000) + return WID_CHAR; + else if (wid_num < 0x2000) + return WID_SHORT; + else if (wid_num < 0x3000) + return WID_INT; + else if (wid_num < 0x4000) + return WID_STR; + else if (wid_num < 0x5000) + return WID_BIN_DATA; + + return WID_UNDEF; +} + + +/* This function extracts the beacon period field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_beacon_period(WILC_Uint8 *data) +{ + WILC_Uint16 bcn_per = 0; + + bcn_per = data[0]; + bcn_per |= (data[1] << 8); + + return bcn_per; +} + +INLINE WILC_Uint32 get_beacon_timestamp_lo(WILC_Uint8 *data) +{ + WILC_Uint32 time_stamp = 0; + WILC_Uint32 index = MAC_HDR_LEN; + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +INLINE UWORD32 get_beacon_timestamp_hi(UWORD8 *data) +{ + UWORD32 time_stamp = 0; + UWORD32 index = (MAC_HDR_LEN + 4); + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +/* This function extracts the 'frame type' bits from the MAC header of the */ +/* input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuBasicFrmType get_type(WILC_Uint8 *header) +{ + return ((tenuBasicFrmType)(header[0] & 0x0C)); +} + +/* This function extracts the 'frame type and sub type' bits from the MAC */ +/* header of the input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuFrmSubtype get_sub_type(WILC_Uint8 *header) +{ + return ((tenuFrmSubtype)(header[0] & 0xFC)); +} + +/* This function extracts the 'to ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE WILC_Uint8 get_to_ds(WILC_Uint8 *header) +{ + return (header[1] & 0x01); +} + +/* This function extracts the 'from ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE WILC_Uint8 get_from_ds(WILC_Uint8 *header) +{ + return ((header[1] & 0x02) >> 1); +} + +/* This function extracts the MAC Address in 'address1' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address1(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 4, 6); +} + +/* This function extracts the MAC Address in 'address2' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address2(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 10, 6); +} + +/* This function extracts the MAC Address in 'address3' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address3(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 16, 6); +} + +/* This function extracts the BSSID from the incoming WLAN packet based on */ +/* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */ +/* variable. */ +INLINE void get_BSSID(WILC_Uint8 *data, WILC_Uint8 *bssid) +{ + if (get_from_ds(data) == 1) + get_address2(data, bssid); + else if (get_to_ds(data) == 1) + get_address1(data, bssid); + else + get_address3(data, bssid); +} + +/* This function extracts the SSID from a beacon/probe response frame */ +INLINE void get_ssid(WILC_Uint8 *data, WILC_Uint8 *ssid, WILC_Uint8 *p_ssid_len) +{ + WILC_Uint8 len = 0; + WILC_Uint8 i = 0; + WILC_Uint8 j = 0; + + len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 1]; + j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 2; + + /* If the SSID length field is set wrongly to a value greater than the */ + /* allowed maximum SSID length limit, reset the length to 0 */ + if (len >= MAX_SSID_LEN) + len = 0; + + for (i = 0; i < len; i++, j++) + ssid[i] = data[j]; + + ssid[len] = '\0'; + + *p_ssid_len = len; +} + +/* This function extracts the capability info field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_cap_info(WILC_Uint8 *data) +{ + WILC_Uint16 cap_info = 0; + WILC_Uint16 index = MAC_HDR_LEN; + tenuFrmSubtype st = BEACON; + + st = get_sub_type(data); + + /* Location of the Capability field is different for Beacon and */ + /* Association frames. */ + if ((st == BEACON) || (st == PROBE_RSP)) + index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN; + + cap_info = data[index]; + cap_info |= (data[index + 1] << 8); + + return cap_info; +} + +/* This function extracts the capability info field from the Association */ +/* response frame. */ +INLINE WILC_Uint16 get_assoc_resp_cap_info(WILC_Uint8 *data) +{ + WILC_Uint16 cap_info = 0; + + cap_info = data[0]; + cap_info |= (data[1] << 8); + + return cap_info; +} + +/* This funcion extracts the association status code from the incoming */ +/* association response frame and returns association status code */ +INLINE WILC_Uint16 get_asoc_status(WILC_Uint8 *data) +{ + WILC_Uint16 asoc_status = 0; + + asoc_status = data[3]; + asoc_status = (asoc_status << 8) | data[2]; + + return asoc_status; +} + +/* This function extracts association ID from the incoming association */ +/* response frame */ +INLINE WILC_Uint16 get_asoc_id(WILC_Uint8 *data) +{ + WILC_Uint16 asoc_id = 0; + + asoc_id = data[4]; + asoc_id |= (data[5] << 8); + + return asoc_id; +} + +/** + * @brief initializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_SemaphoreAttrs strSemSendPktAttrs; + tstrWILC_SemaphoreAttrs strSemPktRespAttrs; + + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit() \n"); + + WILC_SemaphoreFillDefault(&strSemSendPktAttrs); + strSemSendPktAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&SemHandleSendPkt, &strSemSendPktAttrs); + + WILC_SemaphoreFillDefault(&strSemPktRespAttrs); + strSemPktRespAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&SemHandlePktResp, &strSemPktRespAttrs); + + gps8ConfigPacket = (WILC_Sint8 *)WILC_MALLOC(MAX_PACKET_BUFF_SIZE); + if (gps8ConfigPacket == NULL) { + PRINT_ER("failed in gps8ConfigPacket allocation \n"); + s32Error = WILC_NO_MEM; + goto _fail_; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); +_fail_: + return s32Error; +} + +WILC_Uint8 *get_tim_elm(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen, WILC_Uint16 u16TagParamOffset) +{ + WILC_Uint16 u16index = 0; + + /*************************************************************************/ + /* Beacon Frame - Frame Body */ + /* --------------------------------------------------------------------- */ + /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */ + /* --------------------------------------------------------------------- */ + /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */ + /* --------------------------------------------------------------------- */ + /* */ + /*************************************************************************/ + + u16index = u16TagParamOffset; + + /* Search for the TIM Element Field and return if the element is found */ + while (u16index < (u16RxLen - FCS_LEN)) { + if (pu8msa[u16index] == ITIM) { + return(&pu8msa[u16index]); + } else { + u16index += (IE_HDR_LEN + pu8msa[u16index + 1]); + } + } + + return(0); +} + +/* This function gets the current channel information from + * the 802.11n beacon/probe response frame */ +WILC_Uint8 get_current_channel_802_11n(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen) +{ + WILC_Uint16 index; + + index = TAG_PARAM_OFFSET; + while (index < (u16RxLen - FCS_LEN)) { + if (pu8msa[index] == IDSPARMS) + return (pu8msa[index + 2]); + else + /* Increment index by length information and header */ + index += pu8msa[index + 1] + IE_HDR_LEN; + } + + /* Return current channel information from the MIB, if beacon/probe */ + /* response frame does not contain the DS parameter set IE */ + /* return (mget_CurrentChannel() + 1); */ + return 0; /* no MIB here */ +} + +WILC_Uint8 get_current_channel(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen) +{ +#ifdef PHY_802_11n +#ifdef FIVE_GHZ_BAND + /* Get the current channel as its not set in */ + /* 802.11a beacons/probe response */ + return (get_rf_channel() + 1); +#else /* FIVE_GHZ_BAND */ + /* Extract current channel information from */ + /* the beacon/probe response frame */ + return (get_current_channel_802_11n(pu8msa, u16RxLen)); +#endif /* FIVE_GHZ_BAND */ +#else + return 0; +#endif /* PHY_802_11n */ +} + +/** + * @brief parses the received 'N' message + * @details + * @param[in] pu8MsgBuffer The message to be parsed + * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 ParseNetworkInfo(WILC_Uint8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = WILC_NULL; + WILC_Uint8 u8MsgType = 0; + WILC_Uint8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + WILC_Uint16 u16WidLen = 0; + WILC_Uint8 *pu8WidVal = 0; + + u8MsgType = pu8MsgBuffer[0]; + + /* Check whether the received message type is 'N' */ + if ('N' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pu8MsgBuffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); + + /* Extract WID ID */ + u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); + + /* Extract WID Length */ + u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); + + /* Assign a pointer to the WID value */ + pu8WidVal = &pu8MsgBuffer[8]; + + /* parse the WID value of the WID "WID_NEWORK_INFO" */ + { + WILC_Uint8 *pu8msa = 0; + WILC_Uint16 u16RxLen = 0; + WILC_Uint8 *pu8TimElm = 0; + WILC_Uint8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + WILC_Uint8 u8index = 0; + WILC_Uint32 u32Tsf_Lo; + WILC_Uint32 u32Tsf_Hi; + + pstrNetworkInfo = (tstrNetworkInfo *)WILC_MALLOC(sizeof(tstrNetworkInfo)); + WILC_memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo)); + + pstrNetworkInfo->s8rssi = pu8WidVal[0]; + + /* Assign a pointer to msa "Mac Header Start Address" */ + pu8msa = &pu8WidVal[1]; + + u16RxLen = u16WidLen - 1; + + /* parse msa*/ + + /* Get the cap_info */ + pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); + #ifdef WILC_P2P + /* Get time-stamp [Low only 32 bit] */ + pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); + PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); + #endif + + /* Get full time-stamp [Low and High 64 bit] */ + u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); + u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); + + pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((WILC_Uint64)u32Tsf_Hi << 32); + + /* Get SSID */ + get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen)); + + /* Get BSSID */ + get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); + + /* Get the current channel */ + pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN)); + + /* Get beacon period */ + u8index = (MAC_HDR_LEN + TIME_STAMP_LEN); + + pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); + + u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; + + /* Get DTIM Period */ + pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index); + if (pu8TimElm != 0) { + pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; + } + pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; + u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); + + if (u16IEsLen > 0) { + pstrNetworkInfo->pu8IEs = (WILC_Uint8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen); + + WILC_memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen); + } + pstrNetworkInfo->u16IEsLen = u16IEsLen; + + } + + *ppstrNetworkInfo = pstrNetworkInfo; + +ERRORHANDLER: + return s32Error; +} + +/** + * @brief Deallocates the parsed Network Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrNetworkInfo != WILC_NULL) { + if (pstrNetworkInfo->pu8IEs != WILC_NULL) { + WILC_FREE(pstrNetworkInfo->pu8IEs); + pstrNetworkInfo->pu8IEs = WILC_NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrNetworkInfo); + pstrNetworkInfo = WILC_NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +/** + * @brief parses the received Association Response frame + * @details + * @param[in] pu8Buffer The Association Response frame to be parsed + * @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 ParseAssocRespInfo(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectRespInfo *pstrConnectRespInfo = WILC_NULL; + WILC_Uint16 u16AssocRespLen = 0; + WILC_Uint8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + + pstrConnectRespInfo = (tstrConnectRespInfo *)WILC_MALLOC(sizeof(tstrConnectRespInfo)); + WILC_memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo)); + + /* u16AssocRespLen = pu8Buffer[0]; */ + u16AssocRespLen = (WILC_Uint16)u32BufferLen; + + /* get the status code */ + pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer); + if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + + /* get the capability */ + pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer); + + /* get the Association ID */ + pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer); + + /* get the Information Elements */ + pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN]; + u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN); + + pstrConnectRespInfo->pu8RespIEs = (WILC_Uint8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen); + + WILC_memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen); + pstrConnectRespInfo->u16RespIEsLen = u16IEsLen; + } + + *ppstrConnectRespInfo = pstrConnectRespInfo; + + + return s32Error; +} + +/** + * @brief Deallocates the parsed Association Response Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrConnectRespInfo != WILC_NULL) { + if (pstrConnectRespInfo->pu8RespIEs != WILC_NULL) { + WILC_FREE(pstrConnectRespInfo->pu8RespIEs); + pstrConnectRespInfo->pu8RespIEs = WILC_NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrConnectRespInfo); + pstrConnectRespInfo = WILC_NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +#ifndef CONNECT_DIRECT +WILC_Sint32 ParseSurveyResults(WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, + WILC_Uint32 *pu32SurveyResultsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + wid_site_survey_reslts_s *pstrSurveyResults = NULL; + WILC_Uint32 u32SurveyResultsCount = 0; + WILC_Uint32 u32SurveyBytesLength = 0; + WILC_Uint8 *pu8BufferPtr; + WILC_Uint32 u32RcvdSurveyResultsNum = 2; + WILC_Uint8 u8ReadSurveyResFragNum; + WILC_Uint32 i; + WILC_Uint32 j; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0]; + + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + u32SurveyResultsCount++; + } + } + + pstrSurveyResults = (wid_site_survey_reslts_s *)WILC_MALLOC(u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + if (pstrSurveyResults == NULL) { + u32SurveyResultsCount = 0; + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + WILC_memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + + u32SurveyResultsCount = 0; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + pu8BufferPtr = ppu8RcvdSiteSurveyResults[i]; + + u32SurveyBytesLength = pu8BufferPtr[0]; + + /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */ + u8ReadSurveyResFragNum = pu8BufferPtr[1]; + + pu8BufferPtr += 2; + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + WILC_memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH); + pu8BufferPtr += SURVEY_RESULT_LENGTH; + u32SurveyResultsCount++; + } + } + +ERRORHANDLER: + *ppstrSurveyResults = pstrSurveyResults; + *pu32SurveyResultsCount = u32SurveyResultsCount; + + return s32Error; +} + + +WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrSurveyResults != WILC_NULL) { + WILC_FREE(pstrSurveyResults); + } + + return s32Error; +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessCharWid */ +/* */ +/* Description : This function processes a WID of type WID_CHAR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessCharWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint8 *pu8val = (WILC_Uint8 *)ps8WidVal; + WILC_Uint8 u8val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid >> 8) & 0xFF; + if (g_oper_mode == SET_CFG) { + u8val = *pu8val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint8); + + + /* Value */ + pcPacket[s32PktLen++] = u8val; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessShortWid */ +/* */ +/* Description : This function processes a WID of type WID_SHORT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessShortWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint16 *pu16val = (WILC_Uint16 *)ps8WidVal; + WILC_Uint16 u16val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u16val = *pu16val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint16); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u16val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u16val >> 8) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIntWid */ +/* */ +/* Description : This function processes a WID of type WID_INT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIntWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint32 *pu32val = (WILC_Uint32 *)ps8WidVal; + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u32val = *pu32val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIPwid */ +/* */ +/* Description : This function processes a WID of type WID_IP and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIPwid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8ip) +{ + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Convert the IP Address String to Integer */ + conv_ip_to_int(pu8ip, &u32val); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessStrWid */ +/* */ +/* Description : This function processes a WID of type WID_STR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessStrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val, WILC_Sint32 s32ValueSize) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + /* u16MsgLen = WILC_strlen(pu8val); */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessAdrWid */ +/* */ +/* Description : This function processes a WID of type WID_ADR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessAdrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = MAC_ADDR_LEN; + + /* Length */ + pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; + + /* Value */ + extract_mac_addr(pu8val, pcPacket + s32PktLen); + s32PktLen += u16MsgLen; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessBinWid */ +/* */ +/* Description : This function processes a WID of type WID_BIN_DATA and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Name of file containing the binary data in text mode */ +/* */ +/* Globals : */ +/* */ +/* Processing : The binary data is expected to be supplied through a */ +/* file in text mode. This file is expected to be in the */ +/* finject format. It is parsed, converted to binary format */ +/* and copied into g_cfg_pkt for further processing. This */ +/* is obviously a round-about way of processing involving */ +/* multiple (re)conversions between bin & ascii formats. */ +/* But it is done nevertheless to retain uniformity and for */ +/* ease of debugging. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ + +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessBinWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val, WILC_Sint32 s32ValueSize) +{ + /* WILC_ERROR("processing Binary WIDs is not supported \n"); */ + + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + WILC_Uint8 u8checksum = 0; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + /* pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u16MsgLen & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u16MsgLen >> 8) & 0xFF); + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + + /* checksum */ + for (idx = 0; idx < u16MsgLen; idx++) + u8checksum += pcPacket[MSG_HEADER_LEN + idx + 4]; + + pcPacket[s32PktLen++] = u8checksum; + } + *ps32PktLen = s32PktLen; +} + + +/*****************************************************************************/ +/* */ +/* Function Name : further_process_response */ +/* */ +/* Description : This function parses the response frame got from the */ +/* device. */ +/* */ +/* Inputs : 1) The received response frame */ +/* 2) WID */ +/* 3) WID Length */ +/* 4) Output file handle */ +/* 5) Process Wid Number(i.e wid from --widn switch) */ +/* 6) Index the array in the Global Wid Structure. */ +/* */ +/* Globals : g_wid_num, gastrWIDs */ +/* */ +/* Processing : This function parses the response of the device depending*/ +/* WID type and writes it to the output file in Hex or */ +/* decimal notation depending on the --getx or --get switch.*/ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -2 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2009 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 further_process_response(WILC_Uint8 *resp, + WILC_Uint16 u16WIDid, + WILC_Uint16 cfg_len, + WILC_Bool process_wid_num, + WILC_Uint32 cnt, + tstrWID *pstrWIDresult) +{ + WILC_Uint32 retval = 0; + WILC_Uint32 idx = 0; + WILC_Uint8 cfg_chr = 0; + WILC_Uint16 cfg_sht = 0; + WILC_Uint32 cfg_int = 0; + WILC_Uint8 cfg_str[256] = {0}; + tenuWIDtype enuWIDtype = WID_UNDEF; + + if (process_wid_num) { + enuWIDtype = get_wid_type(g_wid_num); + } else { + enuWIDtype = gastrWIDs[cnt].enuWIDtype; + } + + + switch (enuWIDtype) { + case WID_CHAR: + cfg_chr = resp[idx]; + /*Set local copy of WID*/ + *(pstrWIDresult->ps8WidVal) = cfg_chr; + break; + + case WID_SHORT: + { + WILC_Uint16 *pu16val = (WILC_Uint16 *)(pstrWIDresult->ps8WidVal); + cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)(WILC_Sint32)cfg_sht; */ + *pu16val = cfg_sht; + break; + } + + case WID_INT: + { + WILC_Uint32 *pu32val = (WILC_Uint32 *)(pstrWIDresult->ps8WidVal); + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)cfg_int; */ + *pu32val = cfg_int; + break; + } + + case WID_STR: + WILC_memcpy(cfg_str, resp + idx, cfg_len); + /* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */ + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); /* mostafa: no need currently for the extra NULL byte */ + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("allocated WID buffer length is smaller than the received WID Length \n"); + retval = -2; + } + + break; + + case WID_ADR: + create_mac_addr(cfg_str, resp + idx); + + WILC_strncpy(pstrWIDresult->ps8WidVal, cfg_str, WILC_strlen(cfg_str)); + pstrWIDresult->ps8WidVal[WILC_strlen(cfg_str)] = '\0'; + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_IP: + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + conv_int_to_ip(cfg_str, cfg_int); + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_BIN_DATA: + #if 0 + /* FILE *fp_bin = NULL; */ + WILC_Uint8 first_bin_wid = 1; + if (first_bin_wid) { + /* fp_bin = fopen("wid_response.bin","wb"); */ + first_bin_wid = 0; + } else { + /* fp_bin = fopen("wid_response.bin","ab"); */ + } + + if (/*fp_bin == NULL*/ 0) { + PRINT_ER("Error: Could not open wid_response.bin for write\n"); + return -2; + } + + /* fwrite(resp + idx, cfg_len, 1, fp_bin); */ + + /* fclose(fp_bin); */ + #endif + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len); + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n", retval); + retval = -2; + } + break; + + default: + PRINT_ER("ERROR: Check config database: Error(%d)\n", retval); + retval = -2; + break; + } + + return retval; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ParseResponse */ +/* */ +/* Description : This function parses the command-line options and */ +/* creates the config packets which can be sent to the WLAN */ +/* station. */ +/* */ +/* Inputs : 1) The received response frame */ +/* */ +/* Globals : g_opt_list, gastrWIDs */ +/* */ +/* Processing : This function parses the options and creates different */ +/* types of packets depending upon the WID-type */ +/* corresponding to the option. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -1 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 ParseResponse(WILC_Uint8 *resp, tstrWID *pstrWIDcfgResult) +{ + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDid = 0; + WILC_Uint16 cfg_len = 0; + tenuWIDtype enuWIDtype = WID_UNDEF; + WILC_Bool num_wid_processed = WILC_FALSE; + WILC_Uint32 cnt = 0; + WILC_Uint32 idx = 0; + WILC_Uint32 ResCnt = 0; + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != resp[0]) { + PRINT_INFO(CORECONFIG_DBG, "Received Message format incorrect.\n"); + return -1; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(resp[2], resp[3]); + Res_Len = u16RespLen; + + for (idx = MSG_HEADER_LEN; idx < u16RespLen; ) { + u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]); + cfg_len = resp[idx + 2]; + /* Incase of Bin Type Wid, the length is given by two byte field */ + enuWIDtype = get_wid_type(u16WIDid); + if (WID_BIN_DATA == enuWIDtype) { + cfg_len |= ((WILC_Uint16)resp[idx + 3] << 8) & 0xFF00; + idx++; + } + idx += 3; + if ((u16WIDid == g_wid_num) && (num_wid_processed == WILC_FALSE)) { + num_wid_processed = WILC_TRUE; + + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_TRUE, 0, &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } else { + for (cnt = 0; cnt < g_num_total_switches; cnt++) { + if (gastrWIDs[cnt].u16WIDid == u16WIDid) { + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_FALSE, cnt, + &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } + } + } + idx += cfg_len; + /* In case if BIN type Wid, The last byte of the Cfg packet is the */ + /* Checksum. The WID Length field does not accounts for the checksum. */ + /* The Checksum is discarded. */ + if (WID_BIN_DATA == enuWIDtype) { + idx++; + } + } + + return 0; +} + +/** + * @brief parses the write response [just detects its status: success or failure] + * @details + * @param[in] pu8RespBuffer The Response to be parsed + * @return Error code indicating Write Operation status: + * WRITE_RESP_SUCCESS (1) => Write Success. + * WILC_FAIL (-100) => Write Failure. + * @note + * @author Ittiam + * @date 11 Aug 2009 + * @version 1.0 + */ + +WILC_Sint32 ParseWriteResponse(WILC_Uint8 *pu8RespBuffer) +{ + WILC_Sint32 s32Error = WILC_FAIL; + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDtype = (WILC_Uint16)WID_NIL; + + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != pu8RespBuffer[0]) { + PRINT_ER("Received Message format incorrect.\n"); + return WILC_FAIL; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(pu8RespBuffer[2], pu8RespBuffer[3]); + + u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]); + + /* Check for WID_STATUS ID and then check the length and status value */ + if ((u16WIDtype == WID_STATUS) && + (pu8RespBuffer[6] == 1) && + (pu8RespBuffer[7] == WRITE_RESP_SUCCESS)) { + s32Error = WRITE_RESP_SUCCESS; + return s32Error; + } + + /* If the length or status are not as expected return failure */ + s32Error = WILC_FAIL; + return s32Error; + +} + +/** + * @brief creates the header of the Configuration Packet + * @details + * @param[in,out] pcpacket The Configuration Packet + * @param[in,out] ps32PacketLength Length of the Configuration Packet + * @return Error code indicating success/failure + * @note + * @author aismail + * @date 18 Feb 2012 + * @version 1.0 + */ + +WILC_Sint32 CreatePacketHeader(WILC_Char *pcpacket, WILC_Sint32 *ps32PacketLength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16MsgLen = (WILC_Uint16)(*ps32PacketLength); + WILC_Uint16 u16MsgInd = 0; + + /* The format of the message is: */ + /* +-------------------------------------------------------------------+ */ + /* | Message Type | Message ID | Message Length |Message body | */ + /* +-------------------------------------------------------------------+ */ + /* | 1 Byte | 1 Byte | 2 Bytes | Message Length - 4 | */ + /* +-------------------------------------------------------------------+ */ + + /* The format of a message body of a message type 'W' is: */ + /* +-------------------------------------------------------------------+ */ + /* | WID0 | WID0 Length | WID0 Value | ......................... | */ + /* +-------------------------------------------------------------------+ */ + /* | 2 Bytes | 1 Byte | WID0 Length | ......................... | */ + /* +-------------------------------------------------------------------+ */ + + + + /* Message Type */ + if (g_oper_mode == SET_CFG) + pcpacket[u16MsgInd++] = WRITE_MSG_TYPE; + else + pcpacket[u16MsgInd++] = QUERY_MSG_TYPE; + + /* Sequence Number */ + pcpacket[u16MsgInd++] = g_seqno++; + + /* Message Length */ + pcpacket[u16MsgInd++] = (WILC_Uint8)(u16MsgLen & 0xFF); + pcpacket[u16MsgInd++] = (WILC_Uint8)((u16MsgLen >> 8) & 0xFF); + + *ps32PacketLength = u16MsgLen; + + return s32Error; +} + +/** + * @brief creates Configuration packet based on the Input WIDs + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] ps8packet The created Configuration Packet + * @param[out] ps32PacketLength Length of the created Configuration Packet + * @return Error code indicating success/failure + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CreateConfigPacket(WILC_Sint8 *ps8packet, WILC_Sint32 *ps32PacketLength, + tstrWID *pstrWIDs, WILC_Uint32 u32WIDsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint32 u32idx = 0; + *ps32PacketLength = MSG_HEADER_LEN; + for (u32idx = 0; u32idx < u32WIDsCount; u32idx++) { + switch (pstrWIDs[u32idx].enuWIDtype) { + case WID_CHAR: + ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_SHORT: + ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_INT: + ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_STR: + ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + #if 0 + case WID_ADR: + ProcessAdrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + #endif + case WID_IP: + ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_BIN_DATA: + ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + default: + PRINT_ER("ERROR: Check Config database\n"); + } + } + + CreatePacketHeader(ps8packet, ps32PacketLength); + + return s32Error; +} + +WILC_Sint32 ConfigWaitResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32MaxRespBuffLen, WILC_Sint32 *ps32BytesRead, + WILC_Bool bRespRequired) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + /*bug 3878*/ + /*removed to caller function*/ + /*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer; + * gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen; + * gstrConfigPktInfo.bRespRequired = bRespRequired;*/ + + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + WILC_SemaphoreAcquire(&SemHandlePktResp, WILC_NULL); + + *ps32BytesRead = gstrConfigPktInfo.s32BytesRead; + } + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); + + return s32Error; +} + +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * and retrieves the packet response pu8RxResp + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +#ifdef SIMULATION +WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Sint32 err = WILC_SUCCESS; + WILC_Sint32 s32ConfigPacketLen = 0; + WILC_Sint32 s32RcvdRespLen = 0; + + WILC_SemaphoreAcquire(&SemHandleSendPkt, WILC_NULL); + + /*set the packet mode*/ + g_oper_mode = u8Mode; + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + if (CreateConfigPacket(gps8ConfigPacket, &s32ConfigPacketLen, pstrWIDs, u32WIDsCount) != WILC_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } + /*bug 3878*/ + gstrConfigPktInfo.pcRespBuffer = gps8ConfigPacket; + gstrConfigPktInfo.s32MaxRespBuffLen = MAX_PACKET_BUFF_SIZE; + PRINT_INFO(CORECONFIG_DBG, "GLOBAL =bRespRequired =%d\n", bRespRequired); + gstrConfigPktInfo.bRespRequired = bRespRequired; + + s32Error = SendRawPacket(gps8ConfigPacket, s32ConfigPacketLen); + if (s32Error != WILC_SUCCESS) { + goto End_ConfigPkt; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + ConfigWaitResponse(gps8ConfigPacket, MAX_PACKET_BUFF_SIZE, &s32RcvdRespLen, bRespRequired); + + + if (bRespRequired == WILC_TRUE) { + /* If the operating Mode is GET, then we expect a response frame from */ + /* the driver. Hence start listening to the port for response */ + if (g_oper_mode == GET_CFG) { + #if 1 + err = ParseResponse(gps8ConfigPacket, pstrWIDs); + if (err != 0) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + #endif + } else { + err = ParseWriteResponse(gps8ConfigPacket); + if (err != WRITE_RESP_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + } + + + } + + +End_ConfigPkt: + WILC_SemaphoreRelease(&SemHandleSendPkt, WILC_NULL); + + return s32Error; +} +#endif +WILC_Sint32 ConfigProvideResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32RespLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen); + gstrConfigPktInfo.s32BytesRead = s32RespLen; + } else { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen); + gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen; + PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size \n"); + } + + WILC_SemaphoreRelease(&SemHandlePktResp, WILC_NULL); + } + + return s32Error; +} + +/** + * @brief writes the received packet pu8RxPacket in the global Rx FIFO buffer + * @details + * @param[in] pu8RxPacket The received packet + * @param[in] s32RxPacketLen Length of the received packet + * @return Error code indicating success/failure + * @note + * + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 ConfigPktReceived(WILC_Uint8 *pu8RxPacket, WILC_Sint32 s32RxPacketLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8MsgType = 0; + + u8MsgType = pu8RxPacket[0]; + + switch (u8MsgType) { + case 'R': + ConfigProvideResponse(pu8RxPacket, s32RxPacketLen); + + break; + + case 'N': + PRINT_INFO(CORECONFIG_DBG, "NetworkInfo packet received\n"); + NetworkInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'I': + GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'S': + host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen); + break; + + default: + PRINT_ER("ConfigPktReceived(): invalid received msg type at the Core Configurator \n"); + break; + } + + return s32Error; +} + +/** + * @brief Deinitializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorDeInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit() \n"); + + + WILC_SemaphoreDestroy(&SemHandleSendPkt, WILC_NULL); + WILC_SemaphoreDestroy(&SemHandlePktResp, WILC_NULL); + + + if (gps8ConfigPacket != NULL) { + + WILC_FREE(gps8ConfigPacket); + gps8ConfigPacket = NULL; + } + + return s32Error; +} + + +#ifndef SIMULATION +#if WILC_PLATFORM != WILC_WIN32 +/*Using the global handle of the driver*/ +extern wilc_wlan_oup_t *gpstrWlanOps; +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * using driver config layer + * + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 counter = 0, ret = 0; + if (gpstrWlanOps == NULL) { + PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n"); + } + if (gpstrWlanOps->wlan_cfg_set == NULL || + gpstrWlanOps->wlan_cfg_get == NULL) { + PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "SET is initialized\n"); + } + if (u8Mode == GET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter, + (counter == u32WIDsCount - 1)); + if (!gpstrWlanOps->wlan_cfg_get(!counter, + pstrWIDs[counter].u16WIDid, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Get Timed out\n"); + break; + } + } + /** + * get the value + **/ + /* WILC_Sleep(1000); */ + counter = 0; + for (counter = 0; counter < u32WIDsCount; counter++) { + pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value( + pstrWIDs[counter].u16WIDid, + pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize); + + } + } else if (u8Mode == SET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid); + if (!gpstrWlanOps->wlan_cfg_set(!counter, + pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal, + pstrWIDs[counter].s32ValueSize, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Set Timed out\n"); + break; + } + } + } + + return ret; +} +#endif +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigurator.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/coreconfigurator.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +/*! + * @file coreconfigurator.h + * @brief + * @author + * @sa coreconfigurator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGURATOR_H +#define CORECONFIGURATOR_H + +#include "wilc_oswrapper.h" +#include "wilc_wlan_if.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +/* Number of WID Options Supported */ +#define NUM_BASIC_SWITCHES 45 +#define NUM_FHSS_SWITCHES 0 + +#define NUM_RSSI 5 + +#ifdef MAC_802_11N +#define NUM_11N_BASIC_SWITCHES 25 +#define NUM_11N_HUT_SWITCHES 47 +#else /* MAC_802_11N */ +#define NUM_11N_BASIC_SWITCHES 0 +#define NUM_11N_HUT_SWITCHES 0 +#endif /* MAC_802_11N */ + +extern WILC_Uint16 g_num_total_switches; + +#define MAC_HDR_LEN 24 /* No Address4 - non-ESS */ +#define MAX_SSID_LEN 33 +#define FCS_LEN 4 +#define TIME_STAMP_LEN 8 +#define BEACON_INTERVAL_LEN 2 +#define CAP_INFO_LEN 2 +#define STATUS_CODE_LEN 2 +#define AID_LEN 2 +#define IE_HDR_LEN 2 + + +/* Operating Mode: SET */ +#define SET_CFG 0 +/* Operating Mode: GET */ +#define GET_CFG 1 + +#define MAX_PACKET_BUFF_SIZE 1596 + +#define MAX_STRING_LEN 256 +#define MAX_SURVEY_RESULT_FRAG_SIZE MAX_STRING_LEN +#define SURVEY_RESULT_LENGTH 44 +#define MAX_ASSOC_RESP_FRAME_SIZE MAX_STRING_LEN + +#define STATUS_MSG_LEN 12 +#define MAC_CONNECTED 1 +#define MAC_DISCONNECTED 0 + + + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +#define MAKE_WORD16(lsb, msb) ((((WILC_Uint16)(msb) << 8) & 0xFF00) | (lsb)) +#define MAKE_WORD32(lsw, msw) ((((WILC_Uint32)(msw) << 16) & 0xFFFF0000) | (lsw)) + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ +/* WID Data Types */ +#if 0 +typedef enum { + WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7, + WID_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuWIDtype; + +/* WLAN Identifiers */ +typedef enum { + WID_NIL = -1, + /* EMAC Character WID list */ + WID_BSS_TYPE = 0x0000, + WID_CURRENT_TX_RATE = 0x0001, + WID_CURRENT_CHANNEL = 0x0002, + WID_PREAMBLE = 0x0003, + WID_11G_OPERATING_MODE = 0x0004, + WID_STATUS = 0x0005, + WID_11G_PROT_MECH = 0x0006, + WID_SCAN_TYPE = 0x0007, + WID_PRIVACY_INVOKED = 0x0008, + WID_KEY_ID = 0x0009, + WID_QOS_ENABLE = 0x000A, + WID_POWER_MANAGEMENT = 0x000B, + WID_11I_MODE = 0x000C, + WID_AUTH_TYPE = 0x000D, + WID_SITE_SURVEY = 0x000E, + WID_LISTEN_INTERVAL = 0x000F, + WID_DTIM_PERIOD = 0x0010, + WID_ACK_POLICY = 0x0011, + WID_RESET = 0x0012, + WID_PCF_MODE = 0x0013, + WID_CFP_PERIOD = 0x0014, + WID_BCAST_SSID = 0x0015, + WID_PHY_TEST_PATTERN = 0x0016, + WID_DISCONNECT = 0x0016, + WID_READ_ADDR_SDRAM = 0x0017, + WID_TX_POWER_LEVEL_11A = 0x0018, + WID_REKEY_POLICY = 0x0019, + WID_SHORT_SLOT_ALLOWED = 0x001A, + WID_PHY_ACTIVE_REG = 0x001B, + WID_PHY_ACTIVE_REG_VAL = 0x001C, + WID_TX_POWER_LEVEL_11B = 0x001D, + WID_START_SCAN_REQ = 0x001E, + WID_RSSI = 0x001F, + WID_JOIN_REQ = 0x0020, + WID_ANTENNA_SELECTION = 0x0021, + WID_USER_CONTROL_ON_TX_POWER = 0x0027, + WID_MEMORY_ACCESS_8BIT = 0x0029, + WID_UAPSD_SUPPORT_AP = 0x002A, + WID_CURRENT_MAC_STATUS = 0x0031, + WID_AUTO_RX_SENSITIVITY = 0x0032, + WID_DATAFLOW_CONTROL = 0x0033, + WID_SCAN_FILTER = 0x0036, + WID_LINK_LOSS_THRESHOLD = 0x0037, + WID_AUTORATE_TYPE = 0x0038, + WID_CCA_THRESHOLD = 0x0039, + WID_802_11H_DFS_MODE = 0x003B, + WID_802_11H_TPC_MODE = 0x003C, + WID_DEVICE_READY = 0x003D, + WID_PM_NULL_FRAME_INTERVAL = 0x003E, + WID_PM_ACTIVITY_TIMER = 0x003F, + WID_PM_NULL_FRAME_WAIT_ENABLE = 0x0040, + WID_SCAN_WAIT_TIME = 0x0041, + WID_WSC_IE_EN = 0x0042, + WID_WPS_START = 0x0043, + WID_WPS_DEV_MODE = 0x0044, + WID_BT_COEXISTENCE = 0x0050, + WID_TRACKING_ROAMING = 0x0070, + WID_NUM_PKTS_FOR_RSSI_AVG = 0x0071, + WID_FHSS_SCAN_CHAN_INDEX = 0x0072, + WID_FHSS_SCAN_STEP_INDEX = 0x0073, + + /* NMAC Character WID list */ + WID_11N_PROT_MECH = 0x0080, + WID_11N_ERP_PROT_TYPE = 0x0081, + WID_11N_ENABLE = 0x0082, + WID_11N_OPERATING_MODE = 0x0083, + WID_11N_OBSS_NONHT_DETECTION = 0x0084, + WID_11N_HT_PROT_TYPE = 0x0085, + WID_11N_RIFS_PROT_ENABLE = 0x0086, + WID_11N_SMPS_MODE = 0x0087, + WID_11N_CURRENT_TX_MCS = 0x0088, + WID_11N_PRINT_STATS = 0x0089, + WID_HUT_FCS_CORRUPT_MODE = 0x008A, + WID_HUT_RESTART = 0x008B, + WID_HUT_TX_FORMAT = 0x008C, + WID_11N_SHORT_GI_20MHZ_ENABLE = 0x008D, + WID_HUT_BANDWIDTH = 0x008E, + WID_HUT_OP_BAND = 0x008F, + WID_HUT_STBC = 0x0090, + WID_HUT_ESS = 0x0091, + WID_HUT_ANTSET = 0x0092, + WID_HUT_HT_OP_MODE = 0x0093, + WID_HUT_RIFS_MODE = 0x0094, + WID_HUT_SMOOTHING_REC = 0x0095, + WID_HUT_SOUNDING_PKT = 0x0096, + WID_HUT_HT_CODING = 0x0097, + WID_HUT_TEST_DIR = 0x0098, + WID_HUT_CAPTURE_MODE = 0x0099, + WID_HUT_PHY_TEST_MODE = 0x009A, + WID_HUT_PHY_TEST_RATE_HI = 0x009B, + WID_HUT_PHY_TEST_RATE_LO = 0x009C, + WID_HUT_DISABLE_RXQ_REPLENISH = 0x009D, + WID_HUT_KEY_ORIGIN = 0x009E, + WID_HUT_BCST_PERCENT = 0x009F, + WID_HUT_GROUP_CIPHER_TYPE = 0x00A0, + WID_TX_ABORT_CONFIG = 0x00A1, + WID_HOST_DATA_IF_TYPE = 0x00A2, + WID_HOST_CONFIG_IF_TYPE = 0x00A3, + WID_HUT_TSF_TEST_MODE = 0x00A4, + WID_HUT_TSSI_VALUE = 0x00A5, + WID_HUT_PKT_TSSI_VALUE = 0x00A5, + WID_REG_TSSI_11B_VALUE = 0x00A6, + WID_REG_TSSI_11G_VALUE = 0x00A7, + WID_REG_TSSI_11N_VALUE = 0x00A8, + WID_TX_CALIBRATION = 0x00A9, + WID_DSCR_TSSI_11B_VALUE = 0x00AA, + WID_DSCR_TSSI_11G_VALUE = 0x00AB, + WID_DSCR_TSSI_11N_VALUE = 0x00AC, + WID_HUT_RSSI_EX = 0x00AD, + WID_HUT_ADJ_RSSI_EX = 0x00AE, + WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF, + WID_11N_TXOP_PROT_DISABLE = 0x00B0, + WID_TX_POWER_LEVEL_11N = 0x00B1, + WID_HUT_MGMT_PERCENT = 0x00B3, + WID_HUT_MGMT_BCST_PERCENT = 0x00B4, + WID_HUT_MGMT_ALLOW_HT = 0x00B5, + WID_HUT_UC_MGMT_TYPE = 0x00B6, + WID_HUT_BC_MGMT_TYPE = 0x00B7, + WID_HUT_11W_MFP_REQUIRED_TX = 0x00B8, + WID_HUT_11W_MFP_PEER_CAPABLE = 0x00B9, + WID_HUT_11W_TX_IGTK_ID = 0x00BA, + WID_11W_ENABLE = 0x00BB, + WID_11W_MGMT_PROT_REQ = 0x00BC, + WID_USER_SEC_CHANNEL_OFFSET = 0x00C0, + WID_2040_COEXISTENCE = 0x00C1, + WID_HUT_FC_TXOP_MOD = 0x00C2, + WID_HUT_FC_PROT_TYPE = 0x00C3, + WID_HUT_SEC_CCA_ASSERT = 0x00C4, + WID_2040_ENABLE = 0x00C5, + WID_2040_CURR_CHANNEL_OFFSET = 0x00C6, + WID_2040_40MHZ_INTOLERANT = 0x00C7, + + + /* Custom Character WID list */ + WID_POWER_SAVE = 0x0100, + WID_WAKE_STATUS = 0x0101, + WID_WAKE_CONTROL = 0x0102, + WID_CCA_BUSY_START = 0x0103, + + /* EMAC Short WID list */ + WID_RTS_THRESHOLD = 0x1000, + WID_FRAG_THRESHOLD = 0x1001, + WID_SHORT_RETRY_LIMIT = 0x1002, + WID_LONG_RETRY_LIMIT = 0x1003, + WID_CFP_MAX_DUR = 0x1004, + WID_PHY_TEST_FRAME_LEN = 0x1005, + WID_BEACON_INTERVAL = 0x1006, + WID_MEMORY_ACCESS_16BIT = 0x1008, + WID_RX_SENSE = 0x100B, + WID_ACTIVE_SCAN_TIME = 0x100C, + WID_PASSIVE_SCAN_TIME = 0x100D, + WID_SITE_SURVEY_SCAN_TIME = 0x100E, + WID_JOIN_START_TIMEOUT = 0x100F, + WID_AUTH_TIMEOUT = 0x1010, + WID_ASOC_TIMEOUT = 0x1011, + WID_11I_PROTOCOL_TIMEOUT = 0x1012, + WID_EAPOL_RESPONSE_TIMEOUT = 0x1013, + WID_WPS_PASS_ID = 0x1017, + WID_WPS_CONFIG_METHOD = 0x1018, + WID_FHSS_INIT_SCAN_TIME = 0x1070, + WID_FHSS_ROAM_SCAN_TIME = 0x1071, + + /* NMAC Short WID list */ + WID_11N_RF_REG_VAL = 0x1080, + WID_HUT_FRAME_LEN = 0x1081, + WID_HUT_TXOP_LIMIT = 0x1082, + WID_HUT_SIG_QUAL_AVG = 0x1083, + WID_HUT_SIG_QUAL_AVG_CNT = 0x1084, + WID_11N_SIG_QUAL_VAL = 0x1085, + WID_HUT_RSSI_EX_COUNT = 0x1086, + WID_HUT_UC_MGMT_FRAME_LEN = 0x1088, + WID_HUT_BC_MGMT_FRAME_LEN = 0x1089, + + /* Custom Short WID list */ + + WID_CCA_BUSY_STATUS = 0x1100, + + /* EMAC Integer WID list */ + WID_FAILED_COUNT = 0x2000, + WID_RETRY_COUNT = 0x2001, + WID_MULTIPLE_RETRY_COUNT = 0x2002, + WID_FRAME_DUPLICATE_COUNT = 0x2003, + WID_ACK_FAILURE_COUNT = 0x2004, + WID_RECEIVED_FRAGMENT_COUNT = 0x2005, + WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006, + WID_FCS_ERROR_COUNT = 0x2007, + WID_SUCCESS_FRAME_COUNT = 0x2008, + WID_PHY_TEST_PKT_CNT = 0x2009, + WID_HUT_TX_COUNT = 0x200A, + WID_TX_FRAGMENT_COUNT = 0x200B, + WID_TX_MULTICAST_FRAME_COUNT = 0x200C, + WID_RTS_SUCCESS_COUNT = 0x200D, + WID_RTS_FAILURE_COUNT = 0x200E, + WID_WEP_UNDECRYPTABLE_COUNT = 0x200F, + WID_REKEY_PERIOD = 0x2010, + WID_REKEY_PACKET_COUNT = 0x2011, + WID_1X_SERV_ADDR = 0x2012, + WID_STACK_IP_ADDR = 0x2013, + WID_STACK_NETMASK_ADDR = 0x2014, + WID_HW_RX_COUNT = 0x2015, + WID_MEMORY_ADDRESS = 0x201E, + WID_MEMORY_ACCESS_32BIT = 0x201F, + WID_RF_REG_VAL = 0x2021, + WID_FIRMWARE_INFO = 0x2023, + WID_DEV_OS_VERSION = 0x2025, + WID_ROAM_RSSI_THESHOLDS = 0x2070, + WID_TRACK_INTERVAL_SEC = 0x2071, + WID_FHSS_HOPPING_PARAMS = 0x2072, + WID_FHSS_HOP_DWELL_TIME = 0x2073, + + /* NMAC Integer WID list */ + WID_11N_PHY_ACTIVE_REG_VAL = 0x2080, + WID_HUT_NUM_TX_PKTS = 0x2081, + WID_HUT_TX_TIME_TAKEN = 0x2082, + WID_HUT_TX_TEST_TIME = 0x2083, + WID_HUT_LOG_INTERVAL = 0x2084, + + /* EMAC String WID list */ + WID_SSID = 0x3000, + WID_FIRMWARE_VERSION = 0x3001, + WID_OPERATIONAL_RATE_SET = 0x3002, + WID_BSSID = 0x3003, + #if 0 + WID_WEP_KEY_VALUE0 = 0x3004, + #endif + WID_11I_PSK = 0x3008, + WID_11E_P_ACTION_REQ = 0x3009, + WID_1X_KEY = 0x300A, + WID_HARDWARE_VERSION = 0x300B, + WID_MAC_ADDR = 0x300C, + WID_HUT_DEST_ADDR = 0x300D, + /*WID_HUT_STATS = 0x300E,*/ + WID_PHY_VERSION = 0x300F, + WID_SUPP_USERNAME = 0x3010, + WID_SUPP_PASSWORD = 0x3011, + WID_SITE_SURVEY_RESULTS = 0x3012, + WID_RX_POWER_LEVEL = 0x3013, + WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */ + WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */ + WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */ + WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */ + + WID_ASSOC_RES_INFO = 0x3020, + + /* NMAC String WID list */ + WID_11N_P_ACTION_REQ = 0x3080, + WID_HUT_TEST_ID = 0x3081, + WID_PMKID_INFO = 0x3082, + + /* Custom String WID list */ + WID_FLASH_DATA = 0x3100, + WID_EEPROM_DATA = 0x3101, + WID_SERIAL_NUMBER = 0x3102, + + /* EMAC Binary WID list */ + WID_UAPSD_CONFIG = 0x4001, + WID_UAPSD_STATUS = 0x4002, + WID_AC_PARAMS_AP = 0x4003, + WID_AC_PARAMS_STA = 0x4004, + WID_NEWORK_INFO = 0x4005, + WID_WPS_CRED_LIST = 0x4006, + WID_PRIM_DEV_TYPE = 0x4007, + WID_STA_JOIN_INFO = 0x4008, + WID_CONNECTED_STA_LIST = 0x4009, + + /* NMAC Binary WID list */ + WID_11N_AUTORATE_TABLE = 0x4080, + WID_HUT_TX_PATTERN = 0x4081, + WID_HUT_STATS = 0x4082, + WID_HUT_LOG_STATS = 0x4083, + + /*BugID_3746 WID to add IE to be added in next probe request*/ + WID_INFO_ELEMENT_PROBE = 0x4085, + /*BugID_3746 WID to add IE to be added in next associate request*/ + WID_INFO_ELEMENT_ASSOCIATE = 0x4086, + + /* Miscellaneous WIDs */ + WID_ALL = 0x7FFE, + WID_MAX = 0xFFFF +} tenuWIDid; +#endif + +/* Status Codes for Authentication and Association Frames */ +typedef enum { + SUCCESSFUL_STATUSCODE = 0, + UNSPEC_FAIL = 1, + UNSUP_CAP = 10, + REASOC_NO_ASOC = 11, + FAIL_OTHER = 12, + UNSUPT_ALG = 13, + AUTH_SEQ_FAIL = 14, + CHLNG_FAIL = 15, + AUTH_TIMEOUT = 16, + AP_FULL = 17, + UNSUP_RATE = 18, + SHORT_PREAMBLE_UNSUP = 19, + PBCC_UNSUP = 20, + CHANNEL_AGIL_UNSUP = 21, + SHORT_SLOT_UNSUP = 25, + OFDM_DSSS_UNSUP = 26, + CONNECT_STS_FORCE_16_BIT = 0xFFFF +} tenuConnectSts; + +typedef struct { + WILC_Uint16 u16WIDid; + tenuWIDtype enuWIDtype; + WILC_Sint32 s32ValueSize; + WILC_Sint8 *ps8WidVal; + +} tstrWID; + +typedef struct { + WILC_Uint8 u8Full; + WILC_Uint8 u8Index; + WILC_Sint8 as8RSSI[NUM_RSSI]; +} tstrRSSI; +/* This structure is used to support parsing of the received 'N' message */ +typedef struct { + WILC_Sint8 s8rssi; + WILC_Uint16 u16CapInfo; + WILC_Uint8 au8ssid[MAX_SSID_LEN]; + WILC_Uint8 u8SsidLen; + WILC_Uint8 au8bssid[6]; + WILC_Uint16 u16BeaconPeriod; + WILC_Uint8 u8DtimPeriod; + WILC_Uint8 u8channel; + unsigned long u32TimeRcvdInScanCached; /* of type unsigned long to be accepted by the linux kernel macro time_after() */ + unsigned long u32TimeRcvdInScan; + WILC_Bool bNewNetwork; +#ifdef AGING_ALG + WILC_Uint8 u8Found; +#endif +#ifdef WILC_P2P + WILC_Uint32 u32Tsf; /* time-stamp [Low only 32 bit] */ +#endif + WILC_Uint8 *pu8IEs; + WILC_Uint16 u16IEsLen; + void *pJoinParams; + tstrRSSI strRssi; + WILC_Uint64 u64Tsf; /* time-stamp [Low and High 64 bit] */ +} tstrNetworkInfo; + +/* This structure is used to support parsing of the received Association Response frame */ +typedef struct { + WILC_Uint16 u16capability; + WILC_Uint16 u16ConnectStatus; + WILC_Uint16 u16AssocID; + WILC_Uint8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; +} tstrConnectRespInfo; + + +typedef struct { + WILC_Uint8 au8bssid[6]; + WILC_Uint8 *pu8ReqIEs; + size_t ReqIEsLen; + WILC_Uint8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; + WILC_Uint16 u16ConnectStatus; +} tstrConnectInfo; + + + +typedef struct { + WILC_Uint16 u16reason; + WILC_Uint8 *ie; + size_t ie_len; +} tstrDisconnectNotifInfo; + +#ifndef CONNECT_DIRECT +typedef struct wid_site_survey_reslts { + WILC_Char SSID[MAX_SSID_LEN]; + WILC_Uint8 BssType; + WILC_Uint8 Channel; + WILC_Uint8 SecurityStatus; + WILC_Uint8 BSSID[6]; + WILC_Char RxPower; + WILC_Uint8 Reserved; + +} wid_site_survey_reslts_s; +#endif + +extern WILC_Sint32 CoreConfiguratorInit(void); +extern WILC_Sint32 CoreConfiguratorDeInit(void); + +extern WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler); +extern WILC_Sint32 ParseNetworkInfo(WILC_Uint8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); +extern WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo); + +extern WILC_Sint32 ParseAssocRespInfo(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo); +extern WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo); + +#ifndef CONNECT_DIRECT +extern WILC_Sint32 ParseSurveyResults(WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, WILC_Uint32 *pu32SurveyResultsCount); +extern WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults); +#endif + +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *pspacket, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/fifo_buffer.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/fifo_buffer.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + + +#include "wilc_oswrapper.h" +#include "fifo_buffer.h" + + + +WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, WILC_Uint32 u32BufferLength) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = WILC_MALLOC (sizeof (tstrFifoHandler)); + if (pstrFifoHandler) { + WILC_memset (pstrFifoHandler, 0, sizeof (tstrFifoHandler)); + pstrFifoHandler->pu8Buffer = WILC_MALLOC (u32BufferLength); + if (pstrFifoHandler->pu8Buffer) { + tstrWILC_SemaphoreAttrs strSemBufferAttrs; + pstrFifoHandler->u32BufferLength = u32BufferLength; + WILC_memset (pstrFifoHandler->pu8Buffer, 0, u32BufferLength); + /* create semaphore */ + WILC_SemaphoreFillDefault (&strSemBufferAttrs); + strSemBufferAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&pstrFifoHandler->SemBuffer, &strSemBufferAttrs); + *hBuffer = pstrFifoHandler; + } else { + *hBuffer = NULL; + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} +WILC_Uint32 FIFO_DeInit(tHANDLE hFifo) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (pstrFifoHandler->pu8Buffer) { + WILC_FREE (pstrFifoHandler->pu8Buffer); + } else { + u32Error = 1; + } + + WILC_SemaphoreDestroy (&pstrFifoHandler->SemBuffer, WILC_NULL); + + WILC_FREE (pstrFifoHandler); + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler && pu32BytesRead) { + if (pstrFifoHandler->u32TotalBytes) { + if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) { + if (u32BytesToRead > pstrFifoHandler->u32TotalBytes) { + *pu32BytesRead = pstrFifoHandler->u32TotalBytes; + } else { + *pu32BytesRead = u32BytesToRead; + } + if ((pstrFifoHandler->u32ReadOffset + u32BytesToRead) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + *pu32BytesRead); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset += u32BytesToRead; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32ReadOffset; + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + u32FirstPart); + WILC_memcpy(pu8Buffer + u32FirstPart, pstrFifoHandler->pu8Buffer, + u32BytesToRead - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset = u32BytesToRead - u32FirstPart; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + } + WILC_SemaphoreRelease (&pstrFifoHandler->SemBuffer, WILC_NULL); + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (u32BytesToWrite < pstrFifoHandler->u32BufferLength) { + if ((pstrFifoHandler->u32TotalBytes + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength || + bForceOverWrite) { + if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) { + if ((pstrFifoHandler->u32WriteOffset + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32BytesToWrite); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset += u32BytesToWrite; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32WriteOffset; + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32FirstPart); + WILC_memcpy(pstrFifoHandler->pu8Buffer, pu8Buffer + u32FirstPart, + u32BytesToWrite - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset = u32BytesToWrite - u32FirstPart; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + } + /* if data overwriten */ + if (pstrFifoHandler->u32TotalBytes > pstrFifoHandler->u32BufferLength) { + /* adjust read offset to the oldest data available */ + pstrFifoHandler->u32ReadOffset = pstrFifoHandler->u32WriteOffset; + /* data availabe is the buffer length */ + pstrFifoHandler->u32TotalBytes = pstrFifoHandler->u32BufferLength; + } + WILC_SemaphoreRelease(&pstrFifoHandler->SemBuffer, WILC_NULL); + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/fifo_buffer.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/fifo_buffer.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" + + +#define tHANDLE void * + +typedef struct { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32BufferLength; + WILC_Uint32 u32WriteOffset; + WILC_Uint32 u32ReadOffset; + WILC_Uint32 u32TotalBytes; + WILC_SemaphoreHandle SemBuffer; +} tstrFifoHandler; + + +extern WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, + WILC_Uint32 u32BufferLength); +extern WILC_Uint32 FIFO_DeInit(tHANDLE hFifo); +extern WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, + WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead); +extern WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, + WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite); \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/host_interface.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/host_interface.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#include "host_interface.h" +#include "wilc_oswrapper.h" +#include "itypes.h" +#include "coreconfigurator.h" + +extern WILC_Sint32 TransportInit(void); +extern WILC_Sint32 TransportDeInit(void); +extern WILC_Uint8 connecting; + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_TimerHandle hDuringIpTimer; +#endif + +extern WILC_Bool bEnablePS; +/*BugID_5137*/ +extern WILC_Uint8 g_wilc_initialized; +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ + +/* Message types of the Host IF Message Queue*/ +#define HOST_IF_MSG_SCAN ((WILC_Uint16)0) +#define HOST_IF_MSG_CONNECT ((WILC_Uint16)1) +#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO ((WILC_Uint16)2) +#define HOST_IF_MSG_KEY ((WILC_Uint16)3) +#define HOST_IF_MSG_RCVD_NTWRK_INFO ((WILC_Uint16)4) +#define HOST_IF_MSG_RCVD_SCAN_COMPLETE ((WILC_Uint16)5) +#define HOST_IF_MSG_CFG_PARAMS ((WILC_Uint16)6) +#define HOST_IF_MSG_SET_CHANNEL ((WILC_Uint16)7) +#define HOST_IF_MSG_DISCONNECT ((WILC_Uint16)8) +#define HOST_IF_MSG_GET_RSSI ((WILC_Uint16)9) +#define HOST_IF_MSG_GET_CHNL ((WILC_Uint16)10) +#define HOST_IF_MSG_ADD_BEACON ((WILC_Uint16)11) +#define HOST_IF_MSG_DEL_BEACON ((WILC_Uint16)12) +#define HOST_IF_MSG_ADD_STATION ((WILC_Uint16)13) +#define HOST_IF_MSG_DEL_STATION ((WILC_Uint16)14) +#define HOST_IF_MSG_EDIT_STATION ((WILC_Uint16)15) +#define HOST_IF_MSG_SCAN_TIMER_FIRED ((WILC_Uint16)16) +#define HOST_IF_MSG_CONNECT_TIMER_FIRED ((WILC_Uint16)17) +#define HOST_IF_MSG_POWER_MGMT ((WILC_Uint16)18) +#define HOST_IF_MSG_GET_INACTIVETIME ((WILC_Uint16)19) +#define HOST_IF_MSG_REMAIN_ON_CHAN ((WILC_Uint16)20) +#define HOST_IF_MSG_REGISTER_FRAME ((WILC_Uint16)21) +#define HOST_IF_MSG_LISTEN_TIMER_FIRED ((WILC_Uint16)22) +#define HOST_IF_MSG_GET_LINKSPEED ((WILC_Uint16)23) +#define HOST_IF_MSG_SET_WFIDRV_HANDLER ((WILC_Uint16)24) +#define HOST_IF_MSG_SET_MAC_ADDRESS ((WILC_Uint16)25) +#define HOST_IF_MSG_GET_MAC_ADDRESS ((WILC_Uint16)26) +#define HOST_IF_MSG_SET_OPERATION_MODE ((WILC_Uint16)27) +#define HOST_IF_MSG_SET_IPADDRESS ((WILC_Uint16)28) +#define HOST_IF_MSG_GET_IPADDRESS ((WILC_Uint16)29) +#define HOST_IF_MSG_FLUSH_CONNECT ((WILC_Uint16)30) +#define HOST_IF_MSG_GET_STATISTICS ((WILC_Uint16)31) +#define HOST_IF_MSG_SET_MULTICAST_FILTER ((WILC_Uint16)32) +#define HOST_IF_MSG_ADD_BA_SESSION ((WILC_Uint16)33) +#define HOST_IF_MSG_DEL_BA_SESSION ((WILC_Uint16)34) +#define HOST_IF_MSG_Q_IDLE ((WILC_Uint16)35) +#define HOST_IF_MSG_DEL_ALL_STA ((WILC_Uint16)36) +#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS ((WILC_Uint16)34) + +#define HOST_IF_MSG_EXIT ((WILC_Uint16)100) + +#define HOST_IF_SCAN_TIMEOUT 4000 +#define HOST_IF_CONNECT_TIMEOUT 9500 + +#define BA_SESSION_DEFAULT_BUFFER_SIZE 16 +#define BA_SESSION_DEFAULT_TIMEOUT 1000 +#define BLOCK_ACK_REQ_SIZE 0x14 +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/*! + * @struct tstrHostIFCfgParamAttr + * @brief Structure to hold Host IF CFG Params Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 02 April 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFCfgParamAttr { + tstrCfgParamVal pstrCfgParamVal; + +} tstrHostIFCfgParamAttr; + +/*! + * @struct tstrHostIFwpaAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwpaAttr { + WILC_Uint8 *pu8key; + const WILC_Uint8 *pu8macaddr; + WILC_Uint8 *pu8seq; + WILC_Uint8 u8seqlen; + WILC_Uint8 u8keyidx; + WILC_Uint8 u8Keylen; + WILC_Uint8 u8Ciphermode; +} tstrHostIFwpaAttr; + + +/*! + * @struct tstrHostIFwepAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwepAttr { + WILC_Uint8 *pu8WepKey; + WILC_Uint8 u8WepKeylen; + WILC_Uint8 u8Wepidx; + WILC_Uint8 u8mode; + AUTHTYPE_T tenuAuth_type; + +} tstrHostIFwepAttr; + +/*! + * @struct tuniHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFkeyAttr { + tstrHostIFwepAttr strHostIFwepAttr; + tstrHostIFwpaAttr strHostIFwpaAttr; + tstrHostIFpmkidAttr strHostIFpmkidAttr; +} tuniHostIFkeyAttr; + +/*! + * @struct tstrHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFkeyAttr { + tenuKeyType enuKeyType; + WILC_Uint8 u8KeyAction; + tuniHostIFkeyAttr uniHostIFkeyAttr; +} tstrHostIFkeyAttr; + + + + +/*! + * @struct tstrHostIFscanAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFscanAttr { + WILC_Uint8 u8ScanSource; + WILC_Uint8 u8ScanType; + WILC_Uint8 *pu8ChnlFreqList; + WILC_Uint8 u8ChnlListLen; + WILC_Uint8 *pu8IEs; + size_t IEsLen; + tWILCpfScanResult pfScanResult; + void *pvUserArg; + /*BugID_4189*/ + tstrHiddenNetwork strHiddenNetwork; + +} tstrHostIFscanAttr; + +/*! + * @struct tstrHostIFconnectAttr + * @brief Structure to hold Host IF Connect Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFconnectAttr { + WILC_Uint8 *pu8bssid; + WILC_Uint8 *pu8ssid; + size_t ssidLen; + WILC_Uint8 *pu8IEs; + size_t IEsLen; + WILC_Uint8 u8security; + tWILCpfConnectResult pfConnectResult; + void *pvUserArg; + AUTHTYPE_T tenuAuth_type; + WILC_Uint8 u8channel; + void *pJoinParams; +} tstrHostIFconnectAttr; + +/*! + * @struct tstrRcvdGnrlAsyncInfo + * @brief Structure to hold Received General Asynchronous info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdGnrlAsyncInfo { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdGnrlAsyncInfo; + +/*! + * @struct tstrHostIFSetChan + * @brief Set Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetChan { + WILC_Uint8 u8SetChan; +} tstrHostIFSetChan; + +/*! + * @struct tstrHostIFSetChan + * @brief Get Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 01 Jule 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFGetChan { + WILC_Uint8 u8GetChan; +} tstrHostIFGetChan; + +/*bug3819: Add Scan acomplete notification to host*/ +/*! + * @struct tstrScanComplete + * @brief hold received Async. Scan Complete message body + * @details + * @todo + * @sa + * @author zsalah + * @date 25 March 2012 + * @version 1.0 + */ +/*typedef struct _tstrScanComplete + * { + * WILC_Uint8* pu8Buffer; + * WILC_Uint32 u32Length; + * } tstrScanComplete;*/ + +/*! + * @struct tstrHostIFSetBeacon + * @brief Set Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetBeacon { + WILC_Uint32 u32Interval; /*!< Beacon Interval. Period between two successive beacons on air */ + WILC_Uint32 u32DTIMPeriod; /*!< DTIM Period. Indicates how many Beacon frames + * (including the current frame) appear before the next DTIM */ + WILC_Uint32 u32HeadLen; /*!< Length of the head buffer in bytes */ + WILC_Uint8 *pu8Head; /*!< Pointer to the beacon's head buffer. Beacon's head is the part + * from the beacon's start till the TIM element, NOT including the TIM */ + WILC_Uint32 u32TailLen; /*!< Length of the tail buffer in bytes */ + WILC_Uint8 *pu8Tail; /*!< Pointer to the beacon's tail buffer. Beacon's tail starts just + * after the TIM inormation element */ +} tstrHostIFSetBeacon; + + + +/*! + * @struct tstrHostIFDelBeacon + * @brief Del Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFDelBeacon { + WILC_Uint8 u8dummy; +} tstrHostIFDelBeacon; + +/*! + * @struct tstrHostIFSetMulti + * @brief set Multicast filter Address + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + WILC_Bool bIsEnabled; + WILC_Uint32 u32count; +} tstrHostIFSetMulti; + +/*! + * @struct tstrHostIFDelAllSta + * @brief Deauth station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 09 April 2014 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 au8Sta_DelAllSta[MAX_NUM_STA][ETH_ALEN]; + WILC_Uint8 u8Num_AssocSta; +} tstrHostIFDelAllSta; + +/*! + * @struct tstrHostIFDelSta + * @brief Delete station message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 au8MacAddr[ETH_ALEN]; +} tstrHostIFDelSta; + +/*! + * @struct tstrTimerCb + * @brief Timer callback message body + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrTimerCb { + void *pvUsrArg; /*!< Private data passed at timer start */ +} tstrTimerCb; + +/*! + * @struct tstrHostIfPowerMgmtParam + * @brief Power management message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 + */ +typedef struct { + + WILC_Bool bIsEnabled; + WILC_Uint32 u32Timeout; +} tstrHostIfPowerMgmtParam; + +/*! + * @struct tstrHostIFSetIPAddr + * @brief set IP Address message body + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 *au8IPAddr; + WILC_Uint8 idx; +} tstrHostIFSetIPAddr; + +/*! + * @struct tstrHostIfStaInactiveT + * @brief Get station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 16 April 2013 + * @version 1.0 + */ +typedef struct { + WILC_Uint8 mac[6]; + +} tstrHostIfStaInactiveT; +/**/ +/*! + * @union tuniHostIFmsgBody + * @brief Message body for the Host Interface message_q + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFmsgBody { + tstrHostIFscanAttr strHostIFscanAttr; /*!< Host IF Scan Request Attributes message body */ + tstrHostIFconnectAttr strHostIFconnectAttr; /*!< Host IF Connect Request Attributes message body */ + tstrRcvdNetworkInfo strRcvdNetworkInfo; /*!< Received Asynchronous Network Info message body */ + tstrRcvdGnrlAsyncInfo strRcvdGnrlAsyncInfo; /*!< Received General Asynchronous Info message body */ + tstrHostIFkeyAttr strHostIFkeyAttr; /*!<>*/ + tstrHostIFCfgParamAttr strHostIFCfgParamAttr; /*! <CFG Parameter message Body> */ + tstrHostIFSetChan strHostIFSetChan; + tstrHostIFGetChan strHostIFGetChan; + tstrHostIFSetBeacon strHostIFSetBeacon; /*!< Set beacon message body */ + tstrHostIFDelBeacon strHostIFDelBeacon; /*!< Del beacon message body */ + tstrWILC_AddStaParam strAddStaParam; /*!< Add station message body */ + tstrHostIFDelSta strDelStaParam; /*!< Del Station message body */ + tstrWILC_AddStaParam strEditStaParam; /*!< Edit station message body */ + /* tstrScanComplete strScanComplete; / *Received Async. Scan Complete message body* / */ + tstrTimerCb strTimerCb; /*!< Timer callback message body */ + tstrHostIfPowerMgmtParam strPowerMgmtparam; /*!< Power Management message body */ + tstrHostIfStaInactiveT strHostIfStaInactiveT; + tstrHostIFSetIPAddr strHostIfSetIP; + tstrHostIfSetDrvHandler strHostIfSetDrvHandler; + tstrHostIFSetMulti strHostIfSetMulti; + tstrHostIfSetOperationMode strHostIfSetOperationMode; + tstrHostIfSetMacAddress strHostIfSetMacAddress; + tstrHostIfGetMacAddress strHostIfGetMacAddress; + tstrHostIfBASessionInfo strHostIfBASessionInfo; + #ifdef WILC_P2P + tstrHostIfRemainOnChan strHostIfRemainOnChan; + tstrHostIfRegisterFrame strHostIfRegisterFrame; + #endif + WILC_Char *pUserData; + tstrHostIFDelAllSta strHostIFDelAllSta; +} tuniHostIFmsgBody; + +/*! + * @struct tstrHostIFmsg + * @brief Host Interface message + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFmsg { + WILC_Uint16 u16MsgId; /*!< Message ID */ + tuniHostIFmsgBody uniHostIFmsgBody; /*!< Message body */ + void *drvHandler; +} tstrHostIFmsg; + +#ifdef CONNECT_DIRECT +typedef struct _tstrWidJoinReqExt { + WILC_Char SSID[MAX_SSID_LEN]; + WILC_Uint8 u8channel; + WILC_Uint8 BSSID[6]; +} tstrWidJoinReqExt; +#endif + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Struct containg joinParam of each AP*/ +typedef struct _tstrJoinBssParam { + BSSTYPE_T bss_type; + WILC_Uint8 dtim_period; + WILC_Uint16 beacon_period; + WILC_Uint16 cap_info; + WILC_Uint8 au8bssid[6]; + WILC_Char ssid[MAX_SSID_LEN]; + WILC_Uint8 ssidLen; + WILC_Uint8 supp_rates[MAX_RATES_SUPPORTED + 1]; + WILC_Uint8 ht_capable; + WILC_Uint8 wmm_cap; + WILC_Uint8 uapsd_cap; + WILC_Bool rsn_found; + WILC_Uint8 rsn_grp_policy; + WILC_Uint8 mode_802_11i; + WILC_Uint8 rsn_pcip_policy[3]; + WILC_Uint8 rsn_auth_policy[3]; + WILC_Uint8 rsn_cap[2]; + struct _tstrJoinParam *nextJoinBss; + #ifdef WILC_P2P + WILC_Uint32 tsf; + WILC_Uint8 u8NoaEnbaled; + WILC_Uint8 u8OppEnable; + WILC_Uint8 u8CtWindow; + WILC_Uint8 u8Count; + WILC_Uint8 u8Index; + WILC_Uint8 au8Duration[4]; + WILC_Uint8 au8Interval[4]; + WILC_Uint8 au8StartTime[4]; + #endif +} tstrJoinBssParam; +/*Bug4218: Parsing Join Param*/ +/*a linked list table containing needed join parameters entries for each AP found in most recent scan*/ +typedef struct _tstrBssTable { + WILC_Uint8 u8noBssEntries; + tstrJoinBssParam *head; + tstrJoinBssParam *tail; +} tstrBssTable; +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +typedef enum { + SCAN_TIMER = 0, + CONNECT_TIMER = 1, + SCAN_CONNECT_TIMER_FORCE_32BIT = 0xFFFFFFFF +} tenuScanConnTimer; + +/*****************************************************************************/ +/* */ +/* Global Variabls */ +/* */ +/*****************************************************************************/ + + +tstrWILC_WFIDrv *terminated_handle = WILC_NULL; +tstrWILC_WFIDrv *gWFiDrvHandle = WILC_NULL; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +WILC_Bool g_obtainingIP = WILC_FALSE; +#endif +WILC_Uint8 P2P_LISTEN_STATE; +static WILC_ThreadHandle HostIFthreadHandler; +static WILC_MsgQueueHandle gMsgQHostIF; +static WILC_SemaphoreHandle hSemHostIFthrdEnd; + +WILC_SemaphoreHandle hSemDeinitDrvHandle; +static WILC_SemaphoreHandle hWaitResponse; +WILC_SemaphoreHandle hSemHostIntDeinit; +WILC_TimerHandle g_hPeriodicRSSI; + + + +WILC_Uint8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; + +#ifndef CONNECT_DIRECT +static WILC_Uint8 gapu8RcvdSurveyResults[2][MAX_SURVEY_RESULT_FRAG_SIZE]; +#endif + +static WILC_Uint8 gapu8RcvdAssocResp[MAX_ASSOC_RESP_FRAME_SIZE]; + +WILC_Bool gbScanWhileConnected = WILC_FALSE; + +static WILC_Sint8 gs8Rssi; +static WILC_Sint8 gs8lnkspd; +static WILC_Uint8 gu8Chnl; +static WILC_Uint8 gs8SetIP[2][4]; +static WILC_Uint8 gs8GetIP[2][4]; +#ifdef WILC_AP_EXTERNAL_MLME +static WILC_Uint32 gu32InactiveTime; +static WILC_Uint8 gu8DelBcn; +#endif +#ifndef SIMULATION +static WILC_Uint32 gu32WidConnRstHack; +#endif + +/*BugID_5137*/ +WILC_Uint8 *gu8FlushedJoinReq; +WILC_Uint8 *gu8FlushedInfoElemAsoc; +WILC_Uint8 gu8Flushed11iMode; +WILC_Uint8 gu8FlushedAuthType; +WILC_Uint32 gu32FlushedJoinReqSize; +WILC_Uint32 gu32FlushedInfoElemAsocSize; +WILC_Uint32 gu8FlushedJoinReqDrvHandler; +#define REAL_JOIN_REQ 0 +#define FLUSHED_JOIN_REQ 1 +#define FLUSHED_BYTE_POS 79 /* Position the byte indicating flushing in the flushed request */ + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Bug4218: Parsing Join Param*/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +extern void chip_sleep_manually(WILC_Uint32 u32SleepTime); +extern int linux_wlan_get_num_conn_ifcs(void); + +/** + * @brief Handle_SetChannel + * @details Sending config packet to firmware to set channel + * @param[in] tstrHostIFSetChan* pstrHostIFSetChan + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetChannel(void *drvHandler, tstrHostIFSetChan *pstrHostIFSetChan) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Char *)&(pstrHostIFSetChan->u8SetChan); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting channel\n"); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set channel\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +/** + * @brief Handle_SetWfiDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler *pstrHostIfSetDrvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)((pstrHostIfSetDrvHandler->u32Address)); + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_DRV_HANDLER; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetDrvHandler->u32Address); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetDrvHandler->u32Address) == (WILC_Uint32)NULL) { + WILC_SemaphoreRelease(&hSemDeinitDrvHandle, WILC_NULL); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_SetWfiAPDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetOperationMode(void *drvHandler, tstrHostIfSetOperationMode *pstrHostIfSetOperationMode) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_OPERATION_MODE; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetOperationMode->u32Mode); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + PRINT_INFO(HOSTINF_DBG, "(WILC_Uint32)pstrWFIDrv= %x \n", (WILC_Uint32)pstrWFIDrv); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetOperationMode->u32Mode) == (WILC_Uint32)NULL) { + WILC_SemaphoreRelease(&hSemDeinitDrvHandle, WILC_NULL); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_set_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_set_IPAddress(void *drvHandler, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char firmwareIPAddress[4] = {0}; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + if (pu8IPAddr[0] < 192) + pu8IPAddr[0] = 0; + + PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %d.%d.%d.%d \n", idx, pu8IPAddr[0], pu8IPAddr[1], pu8IPAddr[2], pu8IPAddr[3]); + + WILC_memcpy(gs8SetIP[idx], pu8IPAddr, IP_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)pu8IPAddr; + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + + host_int_get_ipaddress((WILC_WFIDrvHandle)drvHandler, firmwareIPAddress, idx); + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to set IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address set\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/** + * @brief Handle_get_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_get_IPAddress(void *drvHandler, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(IP_ALEN); + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", (WILC_Uint8)(strWID.ps8WidVal[0]), (WILC_Uint8)(strWID.ps8WidVal[1]), (WILC_Uint8)(strWID.ps8WidVal[2]), (WILC_Uint8)(strWID.ps8WidVal[3])); + + WILC_memcpy(gs8GetIP[idx], strWID.ps8WidVal, IP_ALEN); + + /*get the value by searching the local copy*/ + WILC_FREE(strWID.ps8WidVal); + + if (WILC_memcmp(gs8GetIP[idx], gs8SetIP[idx], IP_ALEN) != 0) + host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, gs8SetIP[idx], idx); + + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to get IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d \n", idx); + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", gs8GetIP[idx][0], gs8GetIP[idx][1], gs8GetIP[idx][2], gs8GetIP[idx][3]); + PRINT_INFO(HOSTINF_DBG, "\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/*BugId_5077*/ +/** + * @brief Handle_SetMacAddress + * @details Setting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date November 2013 + * @version 7.0 + */ +static WILC_Sint32 Handle_SetMacAddress(void *drvHandler, tstrHostIfSetMacAddress *pstrHostIfSetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + WILC_Uint8 *mac_buf = (WILC_Uint8 *)WILC_MALLOC(ETH_ALEN); + if (mac_buf == NULL) { + PRINT_ER("No buffer to send mac address\n"); + return WILC_FAIL; + } + WILC_memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = mac_buf; + strWID.s32ValueSize = ETH_ALEN; + PRINT_D(GENERIC_DBG, "mac addr = :%x:%x:%x:%x:%x:%x\n", strWID.ps8WidVal[0], strWID.ps8WidVal[1], strWID.ps8WidVal[2], strWID.ps8WidVal[3], strWID.ps8WidVal[4], strWID.ps8WidVal[5]); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_FREE(mac_buf); + return s32Error; +} + + +/*BugID_5213*/ +/** + * @brief Handle_GetMacAddress + * @details Getting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date JAN 2013 + * @version 8.0 + */ +static WILC_Sint32 Handle_GetMacAddress(void *drvHandler, tstrHostIfGetMacAddress *pstrHostIfGetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pstrHostIfGetMacAddress->u8MacAddress; + strWID.s32ValueSize = ETH_ALEN; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to get mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; +} + + +/** + * @brief Handle_CfgParam + * @details Sending config packet to firmware to set CFG params + * @param[in] tstrHostIFCfgParamAttr* strHostIFCfgParamAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_CfgParam(void *drvHandler, tstrHostIFCfgParamAttr *strHostIFCfgParamAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[32]; + WILC_Uint8 u8WidCnt = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + + PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); + + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BSS_TYPE) { + /*----------------------------------------------------------*/ + /*Input Value: INFRASTRUCTURE = 1, */ + /* INDEPENDENT= 2, */ + /* ANY_BSS= 3 */ + /*----------------------------------------------------------*/ + /* validate input then copy>> need to check value 4 and 5 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.bss_type < 6) { + strWIDList[u8WidCnt].u16WIDid = WID_BSS_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.bss_type = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTH_TYPE) { + /*------------------------------------------------------*/ + /*Input Values: OPEN_SYSTEM = 0, */ + /* SHARED_KEY = 1, */ + /* ANY = 2 */ + /*------------------------------------------------------*/ + /*validate Possible values*/ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 1 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 2 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 5) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.auth_type = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTHEN_TIMEOUT) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TIMEOUT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & POWER_MANAGEMENT) { + /*-----------------------------------------------------------*/ + /*Input Values: NO_POWERSAVE = 0, */ + /* MIN_FAST_PS = 1, */ + /* MAX_FAST_PS = 2, */ + /* MIN_PSPOLL_PS = 3, */ + /* MAX_PSPOLL_PS = 4 */ + /*----------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode < 5) { + strWIDList[u8WidCnt].u16WIDid = WID_POWER_MANAGEMENT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.power_mgmt_mode = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_SHORT) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_LONG) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_LONG_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & FRAG_THRESHOLD) { + + if (strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold < 7937) { + strWIDList[u8WidCnt].u16WIDid = WID_FRAG_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RTS_THRESHOLD) { + /* range 256 to 65535 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_RTS_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PREAMBLE) { + /*-----------------------------------------------------*/ + /*Input Values: Short= 0, */ + /* Long= 1, */ + /* Auto= 2 */ + /*------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_PREAMBLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.preamble_type = strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SHORT_SLOT_ALLOWED) { + if (strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_SLOT_ALLOWED; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.short_slot_allowed = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & TXOP_PROT_DISABLE) { + /*Description: used to Disable RTS-CTS protection for TXOP burst*/ + /*transmission when the acknowledgement policy is No-Ack or Block-Ack */ + /* this information is useful for external supplicant */ + /*Input Values: 1 for enable and 0 for disable. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_11N_TXOP_PROT_DISABLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.txop_prot_disabled = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BEACON_INTERVAL) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_BEACON_INTERVAL; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & DTIM_PERIOD) { + /* range is 1 to 255. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period < 256) { + strWIDList[u8WidCnt].u16WIDid = WID_DTIM_PERIOD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.dtim_period = strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY) { + /*----------------------------------------------------------------------*/ + /*Input Values: SITE_SURVEY_1CH = 0, i.e.: currently set channel */ + /* SITE_SURVEY_ALL_CH = 1, */ + /* SITE_SURVEY_OFF = 2 */ + /*----------------------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.site_survey_enabled = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY_SCAN_TIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & ACTIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_ACTIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PASSIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_PASSIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & CURRENT_TX_RATE) { + CURRENT_TX_RATE_T curr_tx_rate = strHostIFCfgParamAttr->pstrCfgParamVal.curr_tx_rate; + /*----------------------------------------------------------------------*/ + /*Rates: 1 2 5.5 11 6 9 12 18 24 36 48 54 Auto */ + /*InputValues: 1 2 3 4 5 6 7 8 9 10 11 12 0 */ + /*----------------------------------------------------------------------*/ + /* validate rate */ + if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 + || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 + || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 + || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 + || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 + || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { + strWIDList[u8WidCnt].u16WIDid = WID_CURRENT_TX_RATE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&curr_tx_rate; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.curr_tx_rate = (WILC_Uint8)curr_tx_rate; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Error in setting CFG params\n"); + + } + WILC_CATCH(s32Error) + { + } + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + return s32Error; +} + + +/** + * @brief Handle_wait_msg_q_empty + * @details this should be the last msg and then the msg Q becomes idle + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_wait_msg_q_empty(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + g_wilc_initialized = 0; + WILC_SemaphoreRelease(&hWaitResponse, NULL); + return s32Error; +} + +/** + * @brief Handle_Scan + * @details Sending config packet to firmware to set the scan params + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Scan(void *drvHandler, tstrHostIFscanAttr *pstrHostIFscanAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + WILC_Uint32 i; + WILC_Uint8 *pu8Buffer; + WILC_Uint8 valuesize = 0; + WILC_Uint8 *pu8HdnNtwrksWidVal = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state \n", pstrWFIDrv->enuHostIFstate); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult; + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg; + + #ifdef WILC_P2P + #if 0 + if (pstrWFIDrv->enuHostIFstate == HOST_IF_P2P_LISTEN || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED && pstrWFIDrv->u8P2PConnect)) { + PRINT_INFO(GENERIC_DBG, "Busy: State: %d\n", pstrWFIDrv->enuHostIFstate); + PRINT_INFO(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + #endif + + if ((pstrWFIDrv->enuHostIFstate >= HOST_IF_SCANNING) && (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTED)) { + /* here we either in HOST_IF_SCANNING, HOST_IF_WAITING_CONN_REQ or HOST_IF_WAITING_CONN_RESP */ + PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", pstrWFIDrv->enuHostIFstate); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount = 0; + + /*BugID_4189*/ + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_SSID_PROBE_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + valuesize += ((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen) + 1); + } + pu8HdnNtwrksWidVal = WILC_MALLOC(valuesize + 1); + strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal; + if (strWIDList[u32WidsCount].ps8WidVal != WILC_NULL) { + pu8Buffer = strWIDList[u32WidsCount].ps8WidVal; + + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; + + PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum); + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + WILC_memcpy(pu8Buffer, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen); + pu8Buffer += pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + } + + + + strWIDList[u32WidsCount].s32ValueSize = (WILC_Sint32)(valuesize + 1); + u32WidsCount++; + } + + /*filling cfg param array*/ + + /* if((pstrHostIFscanAttr->pu8IEs != NULL) && (pstrHostIFscanAttr->IEsLen != 0)) */ + { + /* IEs to be inserted in Probe Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_PROBE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8IEs; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->IEsLen; + u32WidsCount++; + } + + /*Scan Type*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanType)); + u32WidsCount++; + + /*list of channels to be scanned*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_CHANNEL_LIST; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + + /* Bug 4648: Convert channel numbers to start from 0 not 1. */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL && pstrHostIFscanAttr->u8ChnlListLen > 0) { + int i; + + for (i = 0; i < pstrHostIFscanAttr->u8ChnlListLen; i++) { + if (pstrHostIFscanAttr->pu8ChnlFreqList[i] > 0) { + pstrHostIFscanAttr->pu8ChnlFreqList[i] = pstrHostIFscanAttr->pu8ChnlFreqList[i] - 1; + } + } + } + + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8ChnlFreqList; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->u8ChnlListLen; + u32WidsCount++; + + /*Scan Request*/ + strWIDList[u32WidsCount].u16WIDid = WID_START_SCAN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanSource)); + u32WidsCount++; + + /*keep the state as is , no need to change it*/ + /* gWFiDrvHandle->enuHostIFstate = HOST_IF_SCANNING; */ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + gbScanWhileConnected = WILC_TRUE; + } else if (pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE) { + gbScanWhileConnected = WILC_FALSE; + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } else { + PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n"); + } + + WILC_CATCH(s32Error) + { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + /*if there is an ongoing scan request*/ + Handle_ScanDone(drvHandler, SCAN_EVENT_ABORTED); + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + /* Deallocate pstrHostIFscanAttr->pu8IEs which was previously allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8IEs); + pstrHostIFscanAttr->pu8IEs = NULL; + } + if (pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo != NULL) { + WILC_FREE(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo); + pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo = NULL; + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + if (pu8HdnNtwrksWidVal != NULL) { + WILC_FREE(pu8HdnNtwrksWidVal); + } + + return s32Error; +} + +/** + * @brief Handle_ScanDone + * @details Call scan notification callback function + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ScanDone(void *drvHandler, tenuScanEvent enuEvent) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + WILC_Uint8 u8abort_running_scan; + tstrWID strWID; + + + PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n"); + + /*BugID_4978*/ + /*Ask FW to abort the running scan, if any*/ + if (enuEvent == SCAN_EVENT_ABORTED) { + PRINT_D(GENERIC_DBG, "Abort running scan\n"); + u8abort_running_scan = 1; + strWID.u16WIDid = (WILC_Uint16)WID_ABORT_RUNNING_SCAN; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u8abort_running_scan; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set abort running scan\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + } + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + /*delete current scan request*/ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Connect + * @details Sending config packet to firmware to starting connection + * @param[in] tstrHostIFconnectAttr* pstrHostIFconnectAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Uint8 u8ConnectedSSID[6] = {0}; +static WILC_Sint32 Handle_Connect(void *drvHandler, tstrHostIFconnectAttr *pstrHostIFconnectAttr) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[8]; + WILC_Uint32 u32WidsCount = 0, dummyval = 0; + /* char passphrase[] = "12345678"; */ + #ifndef CONNECT_DIRECT + WILC_Sint32 s32Err = WILC_SUCCESS; + WILC_Uint32 i; + WILC_Uint8 u8bssDscListIndex; + wid_site_survey_reslts_s *pstrSurveyResults = WILC_NULL; + #else + WILC_Uint8 *pu8CurrByte = WILC_NULL; + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + tstrJoinBssParam *ptstrJoinBssParam; + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + #endif + + PRINT_D(GENERIC_DBG, "Handling connect request\n"); + + #ifndef CONNECT_DIRECT + WILC_memset(gapu8RcvdSurveyResults[0], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + WILC_memset(gapu8RcvdSurveyResults[1], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + + + PRINT_D(HOSTINF_DBG, "Getting site survey results\n"); + s32Err = host_int_get_site_survey_results((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdSurveyResults, + MAX_SURVEY_RESULT_FRAG_SIZE); + if (s32Err) { + PRINT_ER("Failed to get site survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } + s32Err = ParseSurveyResults(gapu8RcvdSurveyResults, &pstrSurveyResults, + &pstrWFIDrv->u32SurveyResultsCount); + + + if (s32Err == WILC_SUCCESS) { + /* use the parsed info in pstrSurveyResults, then deallocate it */ + PRINT_D(HOSTINF_DBG, "Copying site survey results in global structure, then deallocate\n"); + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + WILC_memcpy(&pstrWFIDrv->astrSurveyResults[i], &pstrSurveyResults[i], + sizeof(wid_site_survey_reslts_s)); + } + + DeallocateSurveyResults(pstrSurveyResults); + } else { + WILC_ERRORREPORT(s32Error, WILC_FAIL); + PRINT_ER("ParseSurveyResults() Error(%d) \n", s32Err); + } + + + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].SSID, + pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen) == 0) { + PRINT_INFO(HOSTINF_DBG, "Network with required SSID is found %s\n", pstrHostIFconnectAttr->pu8ssid); + if (pstrHostIFconnectAttr->pu8bssid == NULL) { + /* BSSID is not passed from the user, so decision of matching + * is done by SSID only */ + PRINT_INFO(HOSTINF_DBG, "BSSID is not passed from the user\n"); + break; + } else { + /* BSSID is also passed from the user, so decision of matching + * should consider also this passed BSSID */ + + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].BSSID, + pstrHostIFconnectAttr->pu8bssid, + 6) == 0) { + PRINT_INFO(HOSTINF_DBG, "BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if (i < pstrWFIDrv->u32SurveyResultsCount) { + u8bssDscListIndex = i; + + PRINT_INFO(HOSTINF_DBG, "Connecting to network of Bss Idx %d and SSID %s and channel %d \n", + u8bssDscListIndex, pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].SSID, + pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].Channel); + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)&u8bssDscListIndex; + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + + } else { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + + #else + + /* if we try to connect to an already connected AP then discard the request */ + + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + + s32Error = WILC_SUCCESS; + PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); + return s32Error; + } + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + ptstrJoinBssParam = (tstrJoinBssParam *)pstrHostIFconnectAttr->pJoinParams; + if (ptstrJoinBssParam == NULL) { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + +#if 0 + /* if we try to connect to an already connected AP then discard the request */ + PRINT_D(GENERIC_DBG, "Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + PRINT_ER("Discard connect request\n"); + s32Error = WILC_FAIL; + return s32Error; + } +#endif + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + + gu32FlushedInfoElemAsocSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + gu8FlushedInfoElemAsoc = WILC_MALLOC(gu32FlushedInfoElemAsocSize); + memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + gu32FlushedInfoElemAsocSize); + } + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8Flushed11iMode = pstrWFIDrv->strWILC_UsrConnReq.u8security; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8FlushedAuthType = (WILC_Uint8)pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n", + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->u8channel); + + +#ifndef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = MAX_SSID_LEN + 7; + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + if (strWIDList[u32WidsCount].ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + #else + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + /*Sending NoA attributes during connection*/ + strWIDList[u32WidsCount].s32ValueSize = 112; /* 79; */ + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize; + gu8FlushedJoinReq = WILC_MALLOC(gu32FlushedJoinReqSize); + } + if (strWIDList[u32WidsCount].ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + + /* BSS type*/ + *(pu8CurrByte++) = INFRASTRUCTURE; + /* Channel*/ + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + /* Cap Info*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + + /* sa*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* bssid*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* Beacon Period*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + /* DTIM Period*/ + *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period; + PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1))); + /* Supported rates*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1); + pu8CurrByte += (MAX_RATES_SUPPORTED + 1); + + /* wmm cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap; + PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1))); + /* uapsd cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap; + + /* ht cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable; + /* copy this information to the user request */ + pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable; + + /* rsn found*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found; + PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1)); + /* rsn group policy*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy; + PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1))); + /* mode_802_11i*/ + *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i; + PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1))); + /* rsn pcip policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap); + + /*BugID_5137*/ + *(pu8CurrByte++) = REAL_JOIN_REQ; + + #ifdef WILC_P2P + *(pu8CurrByte++) = ptstrJoinBssParam->u8NoaEnbaled; + if (ptstrJoinBssParam->u8NoaEnbaled) { + PRINT_D(HOSTINF_DBG, "NOA present\n"); + + *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Index; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8OppEnable; + + if (ptstrJoinBssParam->u8OppEnable) + *(pu8CurrByte++) = ptstrJoinBssParam->u8CtWindow; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Count; + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Duration, sizeof(ptstrJoinBssParam->au8Duration)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Duration); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Interval, sizeof(ptstrJoinBssParam->au8Interval)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Interval); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof(ptstrJoinBssParam->au8StartTime)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8StartTime); + + } else + PRINT_D(HOSTINF_DBG, "NOA not present\n"); + #endif + + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + #endif /* #ifdef WILC_PARSE_SCAN_IN_HOST*/ + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize); + gu8FlushedJoinReqDrvHandler = (WILC_Uint32)pstrWFIDrv; + } + + PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->pu8bssid, ETH_ALEN); + + PRINT_D(GENERIC_DBG, "save Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "save bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + #endif + + WILC_CATCH(s32Error) + { + tstrConnectInfo strConnectInfo; + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + + PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (pstrHostIFconnectAttr->pfConnectResult != NULL) { + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrHostIFconnectAttr->pfConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrHostIFconnectAttr->pvUserArg); + /*Change state to idle*/ + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* Deallocation */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + } + + PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n"); + /* Deallocate pstrHostIFconnectAttr->pu8bssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8bssid); + pstrHostIFconnectAttr->pu8bssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8ssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8ssid); + pstrHostIFconnectAttr->pu8ssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8IEs which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8IEs); + pstrHostIFconnectAttr->pu8IEs = NULL; + } + + if (pu8CurrByte != WILC_NULL) { + WILC_FREE(pu8CurrByte); + } + return s32Error; +} + +/** + * @brief Handle_FlushConnect + * @details Sending config packet to firmware to flush an old connection + * after switching FW from station one to hybrid one + * @param[in] void * drvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +static WILC_Sint32 Handle_FlushConnect(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + WILC_Uint8 *pu8CurrByte = WILC_NULL; + + + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = gu8FlushedInfoElemAsoc; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedInfoElemAsocSize; + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(gu8Flushed11iMode)); + u32WidsCount++; + + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&gu8FlushedAuthType); + u32WidsCount++; + + + #ifdef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedJoinReqSize; + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)gu8FlushedJoinReq; + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + pu8CurrByte += FLUSHED_BYTE_POS; + *(pu8CurrByte) = FLUSHED_JOIN_REQ; + + u32WidsCount++; + + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, gu8FlushedJoinReqDrvHandler); + if (s32Error) { + PRINT_ER("Handle_Flush_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_ConnectTimeout + * @details Call connect notification callback function indicating connection failure + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ConnectTimeout(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectInfo strConnectInfo; + tstrWID strWID; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + + /* First, we will notify the upper layer with the Connection failure {through the Connect Callback function}, + * then we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + /* Deallocation of strConnectInfo.pu8ReqIEs */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + + /* Here we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + } + + /* Deallocation of the Saved Connect Request in the global Handle */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + /*BugID_5213*/ + /*Freeing flushed join request params on connect timeout*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdNtwrkInfo + * @details Handling received network information + * @param[in] tstrRcvdNetworkInfo* pstrRcvdNetworkInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdNtwrkInfo(void *drvHandler, tstrRcvdNetworkInfo *pstrRcvdNetworkInfo) +{ + WILC_Uint32 i; + WILC_Bool bNewNtwrkFound; + + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = NULL; + void *pJoinParams = NULL; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + bNewNtwrkFound = WILC_TRUE; + PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); + + /*if there is a an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); + ParseNetworkInfo(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo); + if ((pstrNetworkInfo == NULL) + || (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult == WILC_NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* check whether this network is discovered before */ + for (i = 0; i < pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount; i++) { + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) && + (pstrNetworkInfo->au8bssid != NULL)) { + if (WILC_memcmp(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) { + if (pstrNetworkInfo->s8rssi <= pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) { + /*we have already found this network with better rssi, so keep the old cached one and don't + * send anything to the upper layer */ + PRINT_D(HOSTINF_DBG, "Network previously discovered\n"); + goto done; + } else { + /* here the same already found network is found again but with a better rssi, so just update + * the rssi for this cached network and send this updated network to the upper layer but + * don't add a new record for it */ + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi; + bNewNtwrkFound = WILC_FALSE; + break; + } + } + } + } + + if (bNewNtwrkFound == WILC_TRUE) { + /* here it is confirmed that it is a new discovered network, + * so add its record then call the User CallBack function */ + + PRINT_D(HOSTINF_DBG, "New network found\n"); + + if (pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid != NULL) + && (pstrNetworkInfo->au8bssid != NULL)) { + WILC_memcpy(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid, + pstrNetworkInfo->au8bssid, 6); + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount++; + + pstrNetworkInfo->bNewNetwork = WILC_TRUE; + /*Bug4218: Parsing Join Param*/ + /* add new BSS to JoinBssTable */ + #ifdef WILC_PARSE_SCAN_IN_HOST + pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, + pJoinParams); + + + } + } else { + PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit \n"); + } + } else { + pstrNetworkInfo->bNewNetwork = WILC_FALSE; + /* just call the User CallBack function to send the same discovered network with its updated RSSI */ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + } + } + + + WILC_CATCH(s32Error) + { + + } + +done: + /* Deallocate pstrRcvdNetworkInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdNetworkInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdNetworkInfo->pu8Buffer); + pstrRcvdNetworkInfo->pu8Buffer = NULL; + } + + /*free structure allocated*/ + if (pstrNetworkInfo != WILC_NULL) { + DeallocateNetworkInfo(pstrNetworkInfo); + pstrNetworkInfo = WILC_NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdGnrlAsyncInfo + * @details Handling received asynchrous general network information + * @param[in] tstrRcvdGnrlAsyncInfo* pstrRcvdGnrlAsyncInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdGnrlAsyncInfo(void *drvHandler, tstrRcvdGnrlAsyncInfo *pstrRcvdGnrlAsyncInfo) +{ + /* TODO: mostafa: till now, this function just handles only the received mac status msg, */ + /* which carries only 1 WID which have WID ID = WID_STATUS */ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8MsgType = 0; + WILC_Uint8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + WILC_Uint8 u8WidLen = 0; + WILC_Uint8 u8MacStatus; + WILC_Uint8 u8MacStatusReasonCode; + WILC_Uint8 u8MacStatusAdditionalInfo; + tstrConnectInfo strConnectInfo; + tstrDisconnectNotifInfo strDisconnectNotifInfo; + WILC_Sint32 s32Err = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + } + PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", pstrWFIDrv->enuHostIFstate, + pstrRcvdGnrlAsyncInfo->pu8Buffer[7]); + + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) || + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + if ((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) || + (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == WILC_NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + u8MsgType = pstrRcvdGnrlAsyncInfo->pu8Buffer[0]; + + /* Check whether the received message type is 'I' */ + if ('I' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pstrRcvdGnrlAsyncInfo->pu8Buffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[2], pstrRcvdGnrlAsyncInfo->pu8Buffer[3]); + + /* Extract WID ID [expected to be = WID_STATUS] */ + u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[4], pstrRcvdGnrlAsyncInfo->pu8Buffer[5]); + + /* Extract WID Length [expected to be = 1] */ + u8WidLen = pstrRcvdGnrlAsyncInfo->pu8Buffer[6]; + + /* get the WID value [expected to be one of two values: either MAC_CONNECTED = (1) or MAC_DISCONNECTED = (0)] */ + u8MacStatus = pstrRcvdGnrlAsyncInfo->pu8Buffer[7]; + u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->pu8Buffer[8]; + u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->pu8Buffer[9]; + PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + /* our station had sent Association Request frame, so here it will get the Association Response frame then parse it */ + WILC_Uint32 u32RcvdAssocRespInfoLen; + tstrConnectRespInfo *pstrConnectRespInfo = NULL; + + PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (u8MacStatus == MAC_CONNECTED) { + WILC_memset(gapu8RcvdAssocResp, 0, MAX_ASSOC_RESP_FRAME_SIZE); + + host_int_get_assoc_res_info((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdAssocResp, + MAX_ASSOC_RESP_FRAME_SIZE, + &u32RcvdAssocRespInfoLen); + + PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen); + + if (u32RcvdAssocRespInfoLen != 0) { + + PRINT_D(HOSTINF_DBG, "Parsing association response\n"); + s32Err = ParseAssocRespInfo(gapu8RcvdAssocResp, u32RcvdAssocRespInfoLen, + &pstrConnectRespInfo); + if (s32Err) { + PRINT_ER("ParseAssocRespInfo() returned error %d \n", s32Err); + } else { + /* use the necessary parsed Info from the Received Association Response */ + strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus; + + if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n"); + if (pstrConnectRespInfo->pu8RespIEs != NULL) { + strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen; + + + strConnectInfo.pu8RespIEs = (WILC_Uint8 *)WILC_MALLOC(pstrConnectRespInfo->u16RespIEsLen); + WILC_memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs, + pstrConnectRespInfo->u16RespIEsLen); + } + } + + /* deallocate the Assoc. Resp. parsed structure as it is not needed anymore */ + if (pstrConnectRespInfo != NULL) { + DeallocateAssocRespInfo(pstrConnectRespInfo); + pstrConnectRespInfo = NULL; + } + } + } + } + + /* The station has just received mac status and it also received assoc. response which + * it was waiting for. + * So check first the matching between the received mac status and the received status code in Asoc Resp */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { + PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE \n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + } else if (u8MacStatus == MAC_DISCONNECTED) { + PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + } + + /* TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP */ + /* through a structure of type tstrConnectRespInfo */ + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n"); + WILC_memcpy(strConnectInfo.au8bssid, pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + WILC_memcpy(pstrWFIDrv->au8AssociatedBSSID, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN); + } + } + + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + u8MacStatus, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + + /* if received mac status is MAC_CONNECTED and + * received status code in Asoc Resp is SUCCESSFUL_STATUSCODE, change state to CONNECTED + * else change state to IDLE */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTED; + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); + g_obtainingIP = WILC_TRUE; + WILC_TimerStart(&hDuringIpTimer, 10000, WILC_NULL, WILC_NULL); + #endif + + #ifdef WILC_PARSE_SCAN_IN_HOST + /* open a BA session if possible */ + /* if(pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable) */ + + #endif + + /* host_int_addBASession(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid,0, */ + /* BA_SESSION_DEFAULT_BUFFER_SIZE,BA_SESSION_DEFAULT_TIMEOUT); */ + } else { + PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + } + + /* Deallocation */ + if (strConnectInfo.pu8RespIEs != NULL) { + WILC_FREE(strConnectInfo.pu8RespIEs); + strConnectInfo.pu8RespIEs = NULL; + } + + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)) { + /* Disassociation or Deauthentication frame has been received */ + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >> \n\n"); + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + } + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + } else { + PRINT_ER("Connect result callback function is NULL \n"); + } + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + + /* if Information Elements were retrieved from the Received deauth/disassoc frame, then they + * should be deallocated here */ + /* + * if(strDisconnectNotifInfo.ie != NULL) + * { + * WILC_FREE(strDisconnectNotifInfo.ie); + * strDisconnectNotifInfo.ie = NULL; + * } + */ + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + /*BugID_5213*/ + /*Freeing flushed join request params on receiving*/ + /*MAC_DISCONNECTED while connected*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL)) { + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >> \n\n"); + /*Abort the running scan*/ + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + + } + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* Deallocate pstrRcvdGnrlAsyncInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdGnrlAsyncInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdGnrlAsyncInfo->pu8Buffer); + pstrRcvdGnrlAsyncInfo->pu8Buffer = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Key + * @details Sending config packet to firmware to set key + * @param[in] tstrHostIFkeyAttr* pstrHostIFkeyAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static int Handle_Key(void *drvHandler, tstrHostIFkeyAttr *pstrHostIFkeyAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + #ifdef WILC_AP_EXTERNAL_MLME + tstrWID strWIDList[5]; + #endif + WILC_Uint8 i; + WILC_Uint8 *pu8keybuf; + WILC_Sint8 s8idxarray[1]; + WILC_Sint8 ret = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + switch (pstrHostIFkeyAttr->enuKeyType) { + + + case WEP: + +#ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8mode)); + + strWIDList[1].u16WIDid = WID_AUTH_TYPE; + strWIDList[1].enuWIDtype = WID_CHAR; + strWIDList[1].s32ValueSize = sizeof(WILC_Char); + strWIDList[1].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type)); + + strWIDList[2].u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWIDList[2].enuWIDtype = WID_CHAR; + + strWIDList[2].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[2].s32ValueSize = sizeof(WILC_Char); + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWIDList[3].u16WIDid = (WILC_Uint16)WID_WEP_KEY_VALUE; + strWIDList[3].enuWIDtype = WID_STR; + strWIDList[3].s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen; + strWIDList[3].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + + } +#endif + + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + + WILC_memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, 1); + + WILC_memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_WEP_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + } else if (pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY) { + + PRINT_D(HOSTINF_DBG, "Removing key\n"); + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_WEP_KEY; + strWID.enuWIDtype = WID_STR; + + s8idxarray[0] = (WILC_Sint8)pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + strWID.ps8WidVal = s8idxarray; + strWID.s32ValueSize = 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } else { + strWID.u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting default key index\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + break; + + case WPARxGtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + + + if (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq != NULL) + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + /* pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = 0X51; */ + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n"); + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_memcpy(pu8keybuf, pstrWFIDrv->au8AssociatedBSSID, ETH_ALEN); + } else { + PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED \n"); + } + + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } +_WPARxGtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq); + if (ret == -1) + return ret; + + break; + + case WPAPtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(PTK_KEY_MSG_LEN + 1); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | keyidx |Key Length |Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------ |--------------|----------------|---------------| + | 6 bytes | 1 byte | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + WILC_memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN + 1; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(PTK_KEY_MSG_LEN); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = PTK_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + +_WPAPtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + if (ret == -1) + return ret; + + break; + + + case PMKSA: + + PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n"); + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PMKSA Key\n"); + return -1; + } + + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; + + for (i = 0; i < pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; i++) { + + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, ETH_ALEN); + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, PMKID_LEN); + } + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + break; + } + + if (s32Error) + PRINT_ER("Failed to send key config packet\n"); + + + return s32Error; +} + + +/** + * @brief Handle_Disconnect + * @details Sending config packet to firmware to disconnect + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_Disconnect(void *drvHandler) +{ + tstrWID strWID; + + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } else { + tstrDisconnectNotifInfo strDisconnectNotifInfo; + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = WILC_NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + + /*BugID_5193*/ + /*Stop connect timer, if connection in progress*/ + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, + 0, &strDisconnectNotifInfo, pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + } else { + PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL \n"); + } + + gbScanWhileConnected = WILC_FALSE; + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + + /*BugID_5137*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestDisconnectBlock), WILC_NULL); + /* ///////////////////////// */ + +} + + +void resolve_disconnect_aberration(void *drvHandler) +{ + tstrWILC_WFIDrv *pstrWFIDrv; + + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + if (pstrWFIDrv == WILC_NULL) + return; + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTING)) { + PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); + host_int_disconnect((WILC_WFIDrvHandle)pstrWFIDrv, 1); + } +} +static WILC_Sint32 Switch_Log_Terminal(void *drvHandler) +{ + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + static char dummy = 9; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_LOGTerminal_Switch; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &dummy; + strWID.s32ValueSize = sizeof(WILC_Char); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to switch log terminal\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "MAC address set :: \n"); + + + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_GetChnl + * @details Sending config packet to get channel + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_GetChnl(void *drvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&gu8Chnl; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Getting channel value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get channel number\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetCHNL), WILC_NULL); + + return s32Error; + + + +} + + +/** + * @brief Handle_GetRssi + * @details Sending config packet to get RSSI + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_GetRssi(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_RSSI; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8Rssi; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get RSSI value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetRSSI), WILC_NULL); + + +} + + +static void Handle_GetLinkspeed(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + gs8lnkspd = 0; + + strWID.u16WIDid = (WILC_Uint16)WID_LINKSPEED; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8lnkspd; + strWID.s32ValueSize = sizeof(WILC_Char); + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get LINKSPEED value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetLINKSPEED), WILC_NULL); + + +} + +WILC_Sint32 Handle_GetStatistics(void *drvHandler, tstrStatistics *pstrStatistics) +{ + tstrWID strWIDList[5]; + uint32_t u32WidsCount = 0, s32Error = 0; + + strWIDList[u32WidsCount].u16WIDid = WID_LINKSPEED; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u8LinkSpeed)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RSSI; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->s8RSSI)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32RxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxFailureCount)); + u32WidsCount++; + + s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)drvHandler); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + /* WILC_ERRORREPORT(s32Error, s32Error); */ + } + WILC_SemaphoreRelease(&hWaitResponse, NULL); + return 0; + +} + + +#ifdef WILC_AP_EXTERNAL_MLME + + +/** + * @brief Handle_Get_InActiveTime + * @details Sending config packet to set mac adddress for station and + * get inactive time + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Get_InActiveTime(void *drvHandler, tstrHostIfStaInactiveT *strHostIfStaInactiveT) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 *stamac; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_SET_STA_MAC_INACTIVE_TIME; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = ETH_ALEN; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(strWID.s32ValueSize); + + + stamac = strWID.ps8WidVal; + WILC_memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN); + + + PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); + + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to SET incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + strWID.u16WIDid = (WILC_Uint16)WID_GET_INACTIVE_TIME; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&gu32InactiveTime; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", gu32InactiveTime); + + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemInactiveTime), WILC_NULL); + WILC_CATCH(s32Error) + { + + } + + + return s32Error; + + + +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to add beacon + * @param[in] tstrHostIFSetBeacon* pstrSetBeaconParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddBeacon(void *drvHandler, tstrHostIFSetBeacon *pstrSetBeaconParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_BEACON; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen + pstrSetBeaconParam->u32TailLen + 16; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (pstrSetBeaconParam->u32Interval & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32DTIMPeriod & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32HeadLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 24) & 0xFF); + + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Head, pstrSetBeaconParam->u32HeadLen); + pu8CurrByte += pstrSetBeaconParam->u32HeadLen; + + *pu8CurrByte++ = (pstrSetBeaconParam->u32TailLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 24) & 0xFF); + + /* Bug 4599 : if tail length = 0 skip copying */ + if (pstrSetBeaconParam->pu8Tail > 0) + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Tail, pstrSetBeaconParam->u32TailLen); + pu8CurrByte += pstrSetBeaconParam->u32TailLen; + + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send add beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Head); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Tail); +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to delete beacon + * @param[in] tstrHostIFDelBeacon* pstrDelBeacon + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelBeacon(void *drvHandler, tstrHostIFDelBeacon *pstrDelBeacon) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_BEACON; + strWID.enuWIDtype = WID_CHAR; + strWID.s32ValueSize = sizeof(WILC_Char); + strWID.ps8WidVal = &gu8DelBcn; + + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); + /* TODO: build del beacon message*/ + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send delete beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } +} + + +/** + * @brief WILC_HostIf_PackStaParam + * @details Handling packing of the station params in a buffer + * @param[in] WILC_Uint8* pu8Buffer, tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static WILC_Uint32 WILC_HostIf_PackStaParam(WILC_Uint8 *pu8Buffer, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Uint8 *pu8CurrByte; + + pu8CurrByte = pu8Buffer; + + PRINT_D(HOSTINF_DBG, "Packing STA params\n"); + WILC_memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN); + pu8CurrByte += ETH_ALEN; + + *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8NumRates; + if (pstrStationParam->u8NumRates > 0) { + WILC_memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates); + } + pu8CurrByte += pstrStationParam->u8NumRates; + + *pu8CurrByte++ = pstrStationParam->bIsHTSupported; + *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8AmpduParams; + WILC_memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); + pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; + + *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8ASELCap; + + *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF; + + return pu8CurrByte - pu8Buffer; +} + +/** + * @brief Handle_AddStation + * @details Sending config packet to add station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Handling add station\n"); + strWID.u16WIDid = (WILC_Uint16)WID_ADD_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + + PRINT_ER("Failed to send add station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + +/** + * @brief Handle_DelAllSta + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelAllSta(void *drvHandler, tstrHostIFDelAllSta *pstrDelAllStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + WILC_Uint8 i; + UWORD8 au8Zero_Buff[6] = {0}; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_STA; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = (pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *(pu8CurrByte++) = pstrDelAllStaParam->u8Num_AssocSta; + + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pstrDelAllStaParam->au8Sta_DelAllSta[i], au8Zero_Buff, ETH_ALEN)) + WILC_memcpy(pu8CurrByte, pstrDelAllStaParam->au8Sta_DelAllSta[i], ETH_ALEN); + else + continue; + + pu8CurrByte += ETH_ALEN; + } + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + + WILC_SemaphoreRelease(&hWaitResponse, NULL); +} + + +/** + * @brief Handle_DelStation + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelStation(void *drvHandler, tstrHostIFDelSta *pstrDelStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = ETH_ALEN; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + WILC_memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_EditStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_EDIT_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + PRINT_D(HOSTINF_DBG, "Handling edit station\n"); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send edit station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} +#endif /*WILC_AP_EXTERNAL_MLME*/ + +#ifdef WILC_P2P +/** + * @brief Handle_RemainOnChan + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RemainOnChan(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8remain_on_chan_flag; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + /*If it's a pendig remain-on-channel, don't overwrite gWFiDrvHandle values (since incoming msg is garbbage)*/ + if (!pstrWFIDrv->u8RemainOnChan_pendingreq) { + pstrWFIDrv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; + pstrWFIDrv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel; + pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; + } else { + /*Set the channel to use it as a wid val*/ + pstrHostIfRemainOnChan->u16Channel = pstrWFIDrv->strHostIfRemainOnChan.u16Channel; + } + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n"); + pstrWFIDrv->u8RemainOnChan_pendingreq = 1; + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel); + + u8remain_on_chan_flag = WILC_TRUE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = (WILC_Sint8 *)WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = (WILC_Sint8)pstrHostIfRemainOnChan->u16Channel; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + } + + WILC_CATCH(-1) + { + P2P_LISTEN_STATE = 1; + WILC_TimerStart(&(pstrWFIDrv->hRemainOnChannel), pstrHostIfRemainOnChan->u32duration, (void *)pstrWFIDrv, WILC_NULL); + + /*Calling CFG ready_on_channel*/ + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady(pstrWFIDrv->strHostIfRemainOnChan.pVoid); + } + + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + pstrWFIDrv->u8RemainOnChan_pendingreq = 0; + } + return s32Error; +} + +/** + * @brief Handle_RegisterFrame + * @details + * @param[in] + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RegisterFrame(void *drvHandler, tstrHostIfRegisterFrame *pstrHostIfRegisterFrame) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_REGISTER_FRAME; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = WILC_MALLOC(sizeof(WILC_Uint16) + 2); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg; + *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; + WILC_memcpy(pu8CurrByte, &(pstrHostIfRegisterFrame->u16FrameType), sizeof(WILC_Uint16)); + + + strWID.s32ValueSize = sizeof(WILC_Uint16) + 2; + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to frame register config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + +/** + * @brief Handle_ListenStateExpired + * @details Handle of listen state expiration + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +#define FALSE_FRMWR_CHANNEL 100 +static WILC_Uint32 Handle_ListenStateExpired(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + WILC_Uint8 u8remain_on_chan_flag; + tstrWID strWID; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n"); + + /*BugID_5477*/ + /*Make sure we are already in listen state*/ + /*This is to handle duplicate expiry messages (listen timer fired and supplicant called cancel_remain_on_channel())*/ + if (P2P_LISTEN_STATE) { + u8remain_on_chan_flag = WILC_FALSE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == WILC_NULL) { + PRINT_ER("Failed to allocate memory\n"); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = FALSE_FRMWR_CHANNEL; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + goto _done_; + } + + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired(pstrWFIDrv->strHostIfRemainOnChan.pVoid + , pstrHostIfRemainOnChan->u32ListenSessionID); + } + P2P_LISTEN_STATE = 0; + } else { + PRINT_D(GENERIC_DBG, "Not in listen state\n"); + s32Error = WILC_FAIL; + } + +_done_: + return s32Error; +} + + +/** + * @brief ListenTimerCB + * @details Callback function of remain-on-channel timer + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static void ListenTimerCB(void *pvArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = pstrWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } +} +#endif + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_PowerManagement(void *drvHandler, tstrHostIfPowerMgmtParam *strPowerMgmtParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Sint8 s8PowerMode; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_POWER_MANAGEMENT; + + if (strPowerMgmtParam->bIsEnabled == WILC_TRUE) { + s8PowerMode = MIN_FAST_PS; + } else { + s8PowerMode = NO_POWERSAVE; + } + PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode); + strWID.ps8WidVal = &s8PowerMode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send power management config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } +} + +/** + * @brief Handle_SetMulticastFilter + * @details Set Multicast filter in firmware + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author asobhy + * @date + * @version 1.0 + */ +static void Handle_SetMulticastFilter(void *drvHandler, tstrHostIFSetMulti *strHostIfSetMulti) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + + PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_SETUP_MULTICAST_FILTER; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = sizeof(tstrHostIFSetMulti) + ((strHostIfSetMulti->u32count) * ETH_ALEN); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (strHostIfSetMulti->bIsEnabled & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 24) & 0xFF); + + *pu8CurrByte++ = (strHostIfSetMulti->u32count & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 24) & 0xFF); + + if ((strHostIfSetMulti->u32count) > 0) + memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN)); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to send setup multicast config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + +} + + +/*BugID_5222*/ +/** + * @brief Handle_AddBASession + * @details Add block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2014 + * @version 9.0 + */ +static WILC_Sint32 Handle_AddBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + int AddbaTimeout = 100; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d \nBufferSize == %d \nSessionTimeOut = %d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u16BufferSize, + strHostIfBASessionInfo->u16SessionTimeout, + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x0; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA Policy*/ + *ptr++ = 1; + /* Buffer size*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF); + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /* ADDBA timeout*/ + *ptr++ = (AddbaTimeout & 0xFF); + *ptr++ = ((AddbaTimeout >> 16) & 0xFF); + /* Group Buffer Max Frames*/ + *ptr++ = 8; + /* Group Buffer Timeout */ + *ptr++ = 0; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* Max Num MSDU */ + *ptr++ = 8; + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /*Ack-Policy */ + *ptr++ = 3; + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + return s32Error; + +} + + +/*BugID_5222*/ +/** + * @brief Handle_DelBASession + * @details Delete block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x3; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; + +} + + +/** + * @brief Handle_DelAllRxBASessions + * @details Delete all Rx BA sessions + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Abdelrahman Sobhy + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelAllRxBASessions(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_RX_BA; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; + +} + +/** + * @brief hostIFthread + * @details Main thread to handle message queue requests + * @param[in] void* pvArg + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void hostIFthread(void *pvArg) +{ + WILC_Uint32 u32Ret; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + while (1) { + WILC_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret, WILC_NULL); + pstrWFIDrv = (tstrWILC_WFIDrv *)strHostIFmsg.drvHandler; + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT) { + PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); + break; + } + + + /*Re-Queue HIF message*/ + if ((!g_wilc_initialized)) { + PRINT_D(GENERIC_DBG, "--WAIT--"); + WILC_Sleep(200); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + continue; + } + + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_CONNECT && pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + WILC_Sleep(2); + continue; + } + + switch (strHostIFmsg.u16MsgId) { + case HOST_IF_MSG_Q_IDLE: + Handle_wait_msg_q_empty(); + break; + + case HOST_IF_MSG_SCAN: + Handle_Scan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr); + break; + + case HOST_IF_MSG_CONNECT: + Handle_Connect(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr); + break; + + /*BugID_5137*/ + case HOST_IF_MSG_FLUSH_CONNECT: + Handle_FlushConnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_NTWRK_INFO: + Handle_RcvdNtwrkInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo); + break; + + case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: + Handle_RcvdGnrlAsyncInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo); + break; + + case HOST_IF_MSG_KEY: + Handle_Key(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr); + break; + + case HOST_IF_MSG_CFG_PARAMS: + + Handle_CfgParam(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr); + break; + + case HOST_IF_MSG_SET_CHANNEL: + Handle_SetChannel(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan); + break; + + case HOST_IF_MSG_DISCONNECT: + Handle_Disconnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_SCAN_COMPLETE: + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); + + /*BugID_5213*/ + /*Allow chip sleep, only if both interfaces are not connected*/ + if (!linux_wlan_get_num_conn_ifcs()) { + chip_sleep_manually(INFINITE_SLEEP_TIME); + } + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_DONE); + + #ifdef WILC_P2P + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + #endif + + break; + + case HOST_IF_MSG_GET_RSSI: + Handle_GetRssi(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_LINKSPEED: + Handle_GetLinkspeed(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_STATISTICS: + Handle_GetStatistics(strHostIFmsg.drvHandler, (tstrStatistics *)strHostIFmsg.uniHostIFmsgBody.pUserData); + break; + + case HOST_IF_MSG_GET_CHNL: + Handle_GetChnl(strHostIFmsg.drvHandler); + break; + +#ifdef WILC_AP_EXTERNAL_MLME + case HOST_IF_MSG_ADD_BEACON: + Handle_AddBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon); + break; + + case HOST_IF_MSG_DEL_BEACON: + Handle_DelBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelBeacon); + break; + + case HOST_IF_MSG_ADD_STATION: + Handle_AddStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strAddStaParam); + break; + + case HOST_IF_MSG_DEL_STATION: + Handle_DelStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strDelStaParam); + break; + + case HOST_IF_MSG_EDIT_STATION: + Handle_EditStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strEditStaParam); + break; + + case HOST_IF_MSG_GET_INACTIVETIME: + Handle_Get_InActiveTime(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT); + break; + +#endif /*WILC_AP_EXTERNAL_MLME*/ + case HOST_IF_MSG_SCAN_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Scan Timeout\n"); + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_ABORTED); + break; + + case HOST_IF_MSG_CONNECT_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Connect Timeout \n"); + Handle_ConnectTimeout(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_POWER_MGMT: + Handle_PowerManagement(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam); + break; + + case HOST_IF_MSG_SET_WFIDRV_HANDLER: + Handle_SetWfiDrvHandler(&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler); + break; + + case HOST_IF_MSG_SET_OPERATION_MODE: + Handle_SetOperationMode(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode); + break; + + case HOST_IF_MSG_SET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_set_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + case HOST_IF_MSG_GET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_get_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + /*BugID_5077*/ + case HOST_IF_MSG_SET_MAC_ADDRESS: + Handle_SetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress); + break; + + /*BugID_5213*/ + case HOST_IF_MSG_GET_MAC_ADDRESS: + Handle_GetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress); + break; + +#ifdef WILC_P2P + case HOST_IF_MSG_REMAIN_ON_CHAN: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n"); + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + case HOST_IF_MSG_REGISTER_FRAME: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n"); + Handle_RegisterFrame(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame); + break; + + case HOST_IF_MSG_LISTEN_TIMER_FIRED: + Handle_ListenStateExpired(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + #endif + case HOST_IF_MSG_SET_MULTICAST_FILTER: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n"); + Handle_SetMulticastFilter(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti); + break; + + /*BugID_5222*/ + case HOST_IF_MSG_ADD_BA_SESSION: + Handle_AddBASession(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: + Handle_DelAllRxBASessions(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_STA: + Handle_DelAllSta(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta); + break; + + default: + PRINT_ER("[Host Interface] undefined Received Msg ID \n"); + break; + } + } + + PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n"); + WILC_SemaphoreRelease(&hSemHostIFthrdEnd, WILC_NULL); + return; + /* do_exit(error); */ + /* PRINT_D(HOSTINF_DBG,"do_exit error code %d\n",error); */ + +} + +static void TimerCB_Scan(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); +} + +static void TimerCB_Connect(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); +} + + +/** + * @brief removes wpa/wpa2 keys + * @details only in BSS STA mode if External Supplicant support is enabled. + * removes all WPA/WPA2 station key entries from MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +/* Check implementation in core adding 9 bytes to the input! */ +WILC_Sint32 host_int_remove_key(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8StaAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8StaAddress; + strWID.s32ValueSize = 6; + + return s32Error; + +} + +/** + * @brief removes WEP key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * remove a WEP key entry from MAC HW. + * The BSS Station automatically finds the index of the entry using its + * BSS ID and removes that entry from the MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note NO need for the STA add since it is not used for processing + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_wep_key(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8keyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Remove Wep Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = REMOVEKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Request to remove WEP key \n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief sets WEP default key + * @details Sets the index of the WEP encryption key in use, + * in the key table + * @param[in,out] handle to the wifi driver + * @param[in] key index ( 0, 1, 2, 3) + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_WEPDefaultKeyID(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8Index) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = DEFAULTKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Default key index\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief sets WEP deafault key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * @param[in] message containing WEP Key in the following format + *|---------------------------------------| + *|Key ID Value | Key Length | Key | + *|-------------|------------|------------| + | 1byte | 1byte | Key Length | + ||---------------------------------------| + | + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_sta(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (WILC_Uint8 *)WILC_MALLOC(u8WepKeylen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, u8WepKeylen); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * + * @brief host_int_add_wep_key_bss_ap + * @details valid only in BSS AP mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 28 FEB 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_ap(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx, WILC_Uint8 u8mode, AUTHTYPE_T tenuAuth_type) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 i; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (INFO) { + for (i = 0; i < u8WepKeylen; i++) + PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]); + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (WILC_Uint8 *)WILC_MALLOC((u8WepKeylen)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, (u8WepKeylen)); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8mode = u8mode; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +#endif +/** + * @brief adds ptk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing PTK Key in the following format + *|-----------------------------------------------------------------------------| + *|Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + *|----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + ||-----------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_ptk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8Ptk, WILC_Uint8 u8PtkKeylen, + const WILC_Uint8 *mac_addr, WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode, WILC_Uint8 u8Idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 u8KeyLen = u8PtkKeylen; + WILC_Uint32 i; + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPAPtk; + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8Idx; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8PtkKeylen); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8Ptk, u8PtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < RX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]); + } + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < TX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]); + } + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr = mac_addr; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue: PTK Key\n"); + + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief adds Rx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] pu8RxGtk : contains temporal key | Rx Mic | Tx Mic + * u8GtkKeylen :The total key length + * + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_rx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxGtk, WILC_Uint8 u8GtkKeylen, + WILC_Uint8 u8KeyIdx, WILC_Uint32 u32KeyRSClen, WILC_Uint8 *KeyRSC, + WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 u8KeyLen = u8GtkKeylen; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + if (KeyRSC != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = (WILC_Uint8 *)WILC_MALLOC(u32KeyRSClen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, + KeyRSC, u32KeyRSClen); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPARxGtk; + strHostIFmsg.drvHandler = hWFIDrv; + + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8RxGtk, u8GtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8KeyIdx; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8seqlen = u32KeyRSClen; + + + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: RX GTK\n"); + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#if 0 +/** + * @brief host_int_add_tx_gtk + * @details adds Tx GTk Key + * @param[in,out] handle to the wifi driver + * @param[in] message containing Tx GTK Key in the following format + *|----------------------------------------------------| + | KeyID | Key Length | Temporal Key | Tx Michael Key | + ||-------|------------|--------------|----------------| + ||1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_tx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8KeyLen, WILC_Uint8 *pu8TxGtk, WILC_Uint8 u8KeyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPATxGtk; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8TxGtk, u8KeyLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: TX GTK\n"); + + /* ////////////// */ + WILC_SemaphoreAcquire(&hSemTestKeyBlock, NULL); + WILC_Sleep(100); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#endif +/** + * @brief host_int_set_pmkid_info + * @details caches the pmkid valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver + * @param[in] message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_pmkid_info(WILC_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr *pu8PmkidInfoArray) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 i; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = PMKSA; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, &pu8PmkidInfoArray->pmkidlist[i].bssid, + ETH_ALEN); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, &pu8PmkidInfoArray->pmkidlist[i].pmkid, + PMKID_LEN); + } + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER(" Error in sending messagequeue: PMKID Info\n"); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the cached the pmkid info + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver, + * message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @param[in] + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_pmkid_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PmkidInfoArray, + WILC_Uint32 u32PmkidInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u32PmkidInfoLen; + strWID.ps8WidVal = pu8PmkidInfoArray; + + return s32Error; +} + +/** + * @brief sets the pass phrase + * @details AP/STA mode. This function gives the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * @param[in] String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PassPhrase, + WILC_Uint8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + /* WILC_Uint8 u8Psklength = WILC_strlen(pu8PassPhrase); */ + /*validating psk length*/ + if ((u8Psklength > 7) && (u8Psklength < 65)) { + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8PassPhrase; + strWID.s32ValueSize = u8Psklength; + } + + return s32Error; +} +/** + * @brief host_int_get_MacAddress + * @details gets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 19 April 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_MAC_ADDRESS; + strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress.u8MacAddress = pu8MacAddress; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get mac address\n"); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + return s32Error; +} + +/** + * @brief host_int_set_MacAddress + * @details sets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 16 July 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); + + /* prepare setting mac address message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MAC_ADDRESS; + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress.u8MacAddress, pu8MacAddress, ETH_ALEN); + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set mac address\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + +} + +/** + * @brief host_int_get_RSNAConfigPSKPassPhrase + * @details gets the pass phrase:AP/STA mode. This function gets the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 *pu8PassPhrase, WILC_Uint8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u8Psklength; + strWID.ps8WidVal = pu8PassPhrase; + + return s32Error; +} + +/** + * @brief host_int_get_site_survey_results + * @details gets the site survey results + * @param[in,out] handle to the wifi driver, + * Message containing site survey results in the + * following format + *|---------------------------------------------------| + | MsgLength | fragNo. | MsgBodyLength | MsgBody | + ||-----------|-----------|---------------|-----------| + | 1 | 1 | 1 | 1 | + | ----------------------------------------- | ---------------- + | + ||---------------------------------------| + | Network1 | Netweork2 | ... | Network5 | + ||---------------------------------------| + | 44 | 44 | ... | 44 | + | -------------------------- | --------------------------------------- + | + ||---------------------------------------------------------------------| + | SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved | + | + | + ||------|----------|---------|----------------|-------|------|---------| + | 33 | 1 | 1 | 1 | 6 | 1 | 1 | + ||---------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +#ifndef CONNECT_DIRECT +WILC_Sint32 host_int_get_site_survey_results(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + WILC_Uint32 u32MaxSiteSrvyFragLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID astrWIDList[2]; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + astrWIDList[0].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[0].enuWIDtype = WID_STR; + astrWIDList[0].ps8WidVal = ppu8RcvdSiteSurveyResults[0]; + astrWIDList[0].s32ValueSize = u32MaxSiteSrvyFragLen; + + astrWIDList[1].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[1].enuWIDtype = WID_STR; + astrWIDList[1].ps8WidVal = ppu8RcvdSiteSurveyResults[1]; + astrWIDList[1].s32ValueSize = u32MaxSiteSrvyFragLen; + + s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to send config packet to get survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +#endif + +/** + * @brief sets a start scan request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 scanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&scanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_start_scan_req + * @details gets a start scan request + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ScanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8ScanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_set_join_req + * @details sets a join request + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the bss descriptor + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_join_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8bssid, + WILC_Uint8 *pu8ssid, size_t ssidLen, + const WILC_Uint8 *pu8IEs, size_t IEsLen, + tWILCpfConnectResult pfConnectResult, void *pvUserArg, + WILC_Uint8 u8security, AUTHTYPE_T tenuAuth_type, + WILC_Uint8 u8channel, + void *pJoinParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == WILC_NULL || pfConnectResult == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (hWFIDrv == NULL) { + PRINT_ER("Driver not initialized: gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + if (pJoinParams == NULL) { + PRINT_ER("Unable to Join - JoinParams is NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } +/* + * if(gWFiDrvHandle->strWILC_UsrScanReq.u32RcvdChCount == 0) + * { + * PRINT_ER("No scan results exist: Scanning should be done\n"); + * WILC_ERRORREPORT(s32Error, WILC_FAIL); + * } + */ + /* prepare the Connect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT; + + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8security = u8security; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.tenuAuth_type = tenuAuth_type; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8channel = u8channel; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pfConnectResult = pfConnectResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pvUserArg = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pJoinParams = pJoinParams; + strHostIFmsg.drvHandler = hWFIDrv; + + if (pu8bssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid, + pu8bssid, 6); + } + + if (pu8ssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.ssidLen = ssidLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(ssidLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid, + + pu8ssid, ssidLen); + } + + if (pu8IEs != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = (WILC_Uint8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs, + pu8IEs, IEsLen); + } + if (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTING) { + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTING; + } else + PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", pstrWFIDrv->enuHostIFstate); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = CONNECT_TIMER; + WILC_TimerStart(&(pstrWFIDrv->hConnectTimer), HOST_IF_CONNECT_TIMEOUT, (void *) hWFIDrv, WILC_NULL); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Flush a join request parameters to FW, but actual connection + * @details The function is called in situation where WILC is connected to AP and + * required to switch to hybrid FW for P2P connection + * @param[in] handle to the wifi driver, + * @return Error code indicating success/failure + * @note + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +WILC_Sint32 host_int_flush_join_req(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + if (!gu8FlushedJoinReq) { + s32Error = WILC_FAIL; + return s32Error; + } + + + if (hWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_FLUSH_CONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Flush join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_disconnect + * @details disconnects from the currently associated network + * @param[in,out] handle to the wifi driver, + * @param[in] Reason Code of the Disconnection + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16ReasonCode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* prepare the Disconnect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_DISCONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send message queue: disconnect\n"); + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestDisconnectBlock), NULL); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_disconnect_station + * @details disconnects a sta + * @param[in,out] handle to the wifi driver, + * @param[in] Association Id of the station to be disconnected + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 assoc_id) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&assoc_id; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_assoc_req_info + * @details gets a Association request info + * @param[in,out] handle to the wifi driver, + * Message containg assoc. req info in the following format + * ------------------------------------------------------------------------ + | Management Frame Format | + ||-------------------------------------------------------------------| + ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS | + ||-------------|--------|--|--|-----|----------------|----------|----| + | 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 | + ||-------------------------------------------------------------------| + | | + | Association Request Frame - Frame Body | + ||-------------------------------------------------------------------| + | Capability Information | Listen Interval | SSID | Supported Rates | + ||------------------------|-----------------|------|-----------------| + | 2 | 2 | 2-34 | 3-10 | + | --------------------------------------------------------------------- + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_req_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocReqInfo, + WILC_Uint32 u32AssocReqInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_REQ_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocReqInfo; + strWID.s32ValueSize = u32AssocReqInfoLen; + + + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. resp info + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_assoc_res_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocRespInfo, + WILC_Uint32 u32MaxAssocRespInfoLen, WILC_Uint32 *pu32RcvdAssocRespInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_RES_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocRespInfo; + strWID.s32ValueSize = u32MaxAssocRespInfoLen; + + + /* Sending Configuration packet */ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send association response config packet\n"); + *pu32RcvdAssocRespInfoLen = 0; + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + *pu32RcvdAssocRespInfoLen = strWID.s32ValueSize; + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details Valid only in STA mode. This function gives the RSSI + * values observed in all the channels at the time of scanning. + * The length of the field is 1 greater that the total number of + * channels supported. Byte 0 contains the number of channels while + * each of Byte N contains the observed RSSI value for the channel index N. + * @param[in,out] handle to the wifi driver, + * array of scanned channels' RSSI + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rx_power_level(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxPowerLevel, + WILC_Uint32 u32RxPowerLevelLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_RX_POWER_LEVEL; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8RxPowerLevel; + strWID.s32ValueSize = u32RxPowerLevelLen; + + + return s32Error; +} + +/** + * @brief sets a channel + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the channel to be set + *|-------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_mac_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ChNum) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the set channel message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_CHANNEL; + strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan.u8SetChan = u8ChNum; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_wait_msg_queue_idle(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_Q_IDLE; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /* wait untill MSG Q is empty */ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; + +} + +WILC_Sint32 host_int_set_wfi_drv_handler(WILC_Uint32 u32address) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_WFIDRV_HANDLER; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address = u32address; + /* strHostIFmsg.drvHandler=hWFIDrv; */ + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + + +WILC_Sint32 host_int_set_operation_mode(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32mode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_OPERATION_MODE; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode.u32Mode = u32mode; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the current channel index + * @details + * @param[in,out] handle to the wifi driver, + * current channel index + *|-----------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-----------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_host_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ChNo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Get Channel Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_CHNL; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetCHNL), NULL); + /* gu8Chnl = 11; */ + + *pu8ChNo = gu8Chnl; + + WILC_CATCH(s32Error) + { + } + + return s32Error; + + +} + + +/** + * @brief host_int_test_set_int_wid + * @details Test function for setting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_set_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Char *)&u32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Test Function: Failed to set wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully set wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_get_inactive_time + * @details + * @param[in,out] handle to the wifi driver, + * current sta macaddress, inactive_time + * @return + * @note + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_get_inactive_time(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *mac, WILC_Uint32 *pu32InactiveTime) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT.mac, + mac, ETH_ALEN); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_INACTIVETIME; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemInactiveTime), NULL); + + *pu32InactiveTime = gu32InactiveTime; + + WILC_CATCH(s32Error) + { + } + + return s32Error; +} +#endif +/** + * @brief host_int_test_get_int_wid + * @details Test function for getting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32* pu32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_get_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 *pu32TestMemAddr) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)pu32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Test Function: Failed to get wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully got wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + + +/** + * @brief host_int_get_rssi + * @details gets the currently maintained RSSI value for the station. + * The received signal strength value in dB. + * The range of valid values is -128 to 0. + * @param[in,out] handle to the wifi driver, + * rssi value in dB + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rssi(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8Rssi) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetRSSI), NULL); + + + if (ps8Rssi == NULL) { + PRINT_ER("RSS pointer value is null"); + return WILC_FAIL; + } + + + *ps8Rssi = gs8Rssi; + + + return s32Error; +} + +WILC_Sint32 host_int_get_link_speed(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8lnkspd) +{ + tstrHostIFmsg strHostIFmsg; + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + + /* prepare the Get LINKSPEED Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_LINKSPEED; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send GET_LINKSPEED to message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetLINKSPEED), NULL); + + + if (ps8lnkspd == NULL) { + PRINT_ER("LINKSPEED pointer value is null"); + return WILC_FAIL; + } + + + *ps8lnkspd = gs8lnkspd; + + + return s32Error; +} + +WILC_Sint32 host_int_get_statistics(WILC_WFIDrvHandle hWFIDrv, tstrStatistics *pstrStatistics) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_STATISTICS; + strHostIFmsg.uniHostIFmsgBody.pUserData = (WILC_Char *)pstrStatistics; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + return s32Error; +} + + +/** + * @brief host_int_scan + * @details scans a set of channels + * @param[in,out] handle to the wifi driver, + * @param[in] Scan source + * Scan Type PASSIVE_SCAN = 0, + * ACTIVE_SCAN = 1 + * Channels Array + * Channels Array length + * Scan Callback function + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_scan(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ScanSource, + WILC_Uint8 u8ScanType, WILC_Uint8 *pu8ChnlFreqList, + WILC_Uint8 u8ChnlListLen, const WILC_Uint8 *pu8IEs, + size_t IEsLen, tWILCpfScanResult ScanResult, + void *pvUserArg, tstrHiddenNetwork *pstrHiddenNetwork) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == WILC_NULL || ScanResult == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + /* prepare the Scan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN; + + if (pstrHiddenNetwork != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.u8ssidnum = pstrHiddenNetwork->u8ssidnum; + + } else + PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); + + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanSource = u8ScanSource; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanType = u8ScanType; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pfScanResult = ScanResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pvUserArg = pvUserArg; + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ChnlListLen = u8ChnlListLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = (WILC_Uint8 *)WILC_MALLOC(u8ChnlListLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList, + pu8ChnlFreqList, u8ChnlListLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = (WILC_Uint8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs, + pu8IEs, IEsLen); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scanning parameters: Error(%d)\n", s32Error); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = SCAN_TIMER; + PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); + WILC_TimerStart(&(pstrWFIDrv->hScanTimer), HOST_IF_SCAN_TIMEOUT, (void *) hWFIDrv, WILC_NULL); + + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +/** + * @brief hif_set_cfg + * @details sets configuration wids values + * @param[in,out] handle to the wifi driver, + * @param[in] WID, WID value + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_set_cfg(WILC_WFIDrvHandle hWFIDrv, tstrCfgParamVal *pstrCfgParamVal) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the WiphyParams Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_CFG_PARAMS; + strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr.pstrCfgParamVal = *pstrCfgParamVal; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + + +/** + * @brief hif_get_cfg + * @details gets configuration wids values + * @param[in,out] handle to the wifi driver, + * WID value + * @param[in] WID, + * @return Error code indicating success/failure + * @note + * @author zsalah + * + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_get_cfg(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16WID, WILC_Uint16 *pu16WID_Value) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); + switch (u16WID) { + + case WID_BSS_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.bss_type; + break; + + case WID_AUTH_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.auth_type; + break; + + case WID_AUTH_TIMEOUT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.auth_timeout; + break; + + case WID_POWER_MANAGEMENT: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.power_mgmt_mode; + break; + + case WID_SHORT_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.short_retry_limit; + break; + + case WID_LONG_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.long_retry_limit; + break; + + case WID_FRAG_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.frag_threshold; + break; + + case WID_RTS_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.rts_threshold; + break; + + case WID_PREAMBLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.preamble_type; + break; + + case WID_SHORT_SLOT_ALLOWED: + *pu16WID_Value = (WILC_Uint16) pstrWFIDrv->strCfgValues.short_slot_allowed; + break; + + case WID_11N_TXOP_PROT_DISABLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.txop_prot_disabled; + break; + + case WID_BEACON_INTERVAL: + *pu16WID_Value = pstrWFIDrv->strCfgValues.beacon_interval; + break; + + case WID_DTIM_PERIOD: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.dtim_period; + break; + + case WID_SITE_SURVEY: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.site_survey_enabled; + break; + + case WID_SITE_SURVEY_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.site_survey_scan_time; + break; + + case WID_ACTIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.active_scan_time; + break; + + case WID_PASSIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.passive_scan_time; + break; + + case WID_CURRENT_TX_RATE: + *pu16WID_Value = pstrWFIDrv->strCfgValues.curr_tx_rate; + break; + + default: + break; + } + + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + WILC_CATCH(s32Error) + { + } + return s32Error; + +} + +/*****************************************************************************/ +/* Notification Functions */ +/*****************************************************************************/ +/** + * @brief notifies host with join and leave requests + * @details This function prepares an Information frame having the + * information about a joining/leaving station. + * @param[in,out] handle to the wifi driver, + * @param[in] 6 byte Sta Adress + * Join or leave flag: + * Join = 1, + * Leave =0 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_join_leave_info_to_host + (WILC_Uint16 assocId, WILC_Uint8 *stationAddr, WILC_Bool joining) +{ +} +/** + * @brief notifies host with stations found in scan + * @details sends the beacon/probe response from scan + * @param[in,out] handle to the wifi driver, + * @param[in] Sta Address, + * Frame length, + * Rssi of the Station found + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +void GetPeriodicRSSI(void *pvArg) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return; + } + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = pstrWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return; + } + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); +} + + +void host_int_send_network_info_to_host + (WILC_Uint8 *macStartAddress, WILC_Uint16 u16RxFrameLen, WILC_Sint8 s8Rssi) +{ +} +/** + * @brief host_int_init + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +static WILC_Uint32 u32Intialized; +static WILC_Uint32 msgQ_created; +static WILC_Uint32 clients_count; + +WILC_Sint32 host_int_init(WILC_WFIDrvHandle *phWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv; + tstrWILC_SemaphoreAttrs strSemaphoreAttrs; + + + /*if(u32Intialized == 1) + * { + * PRINT_D(HOSTINF_DBG,"Host interface is previously initialized\n"); + * *phWFIDrv = (WILC_WFIDrvHandle)gWFiDrvHandle; //Will be adjusted later for P2P + * return 0; + * } */ + PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1); + + gbScanWhileConnected = WILC_FALSE; + + WILC_SemaphoreFillDefault(&strSemaphoreAttrs); + + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hWaitResponse, &strSemaphoreAttrs); + + + + /*Allocate host interface private structure*/ + pstrWFIDrv = (tstrWILC_WFIDrv *)WILC_MALLOC(sizeof(tstrWILC_WFIDrv)); + if (pstrWFIDrv == WILC_NULL) { + /* WILC_ERRORREPORT(s32Error,WILC_NO_MEM); */ + s32Error = WILC_NO_MEM; + PRINT_ER("Failed to allocate memory\n"); + goto _fail_timer_2; + } + WILC_memset(pstrWFIDrv, 0, sizeof(tstrWILC_WFIDrv)); + /*return driver handle to user*/ + *phWFIDrv = (WILC_WFIDrvHandle)pstrWFIDrv; + /*save into globl handle*/ + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + #endif + + PRINT_D(HOSTINF_DBG, "Global handle pointer value=%x\n", (WILC_Uint32)pstrWFIDrv); + /* /////////////////////////////////////// */ + if (clients_count == 0) { + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hSemHostIFthrdEnd, &strSemaphoreAttrs); + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hSemDeinitDrvHandle, &strSemaphoreAttrs); + + /*BugID_5348*/ + strSemaphoreAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&hSemHostIntDeinit, &strSemaphoreAttrs); + } + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemTestKeyBlock), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemTestDisconnectBlock), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetRSSI), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetLINKSPEED), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetCHNL), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemInactiveTime), &strSemaphoreAttrs); + + /* /////////////////////////////////////// */ + + + + PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); + + if (clients_count == 0) { + + s32Error = WILC_MsgQueueCreate(&gMsgQHostIF, WILC_NULL); + + + if (s32Error < 0) { + PRINT_ER("Failed to creat MQ\n"); + goto _fail_; + } + msgQ_created = 1; + s32Error = WILC_ThreadCreate(&HostIFthreadHandler, hostIFthread, WILC_NULL, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Thread\n"); + goto _fail_mq_; + } + s32Error = WILC_TimerCreate(&(g_hPeriodicRSSI), GetPeriodicRSSI, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); + + } + + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hScanTimer), TimerCB_Scan, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_thread_; + } + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hConnectTimer), TimerCB_Connect, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + + + #ifdef WILC_P2P + /*Remain on channel timer*/ + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hRemainOnChannel), ListenTimerCB, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Remain-on-channel Timer\n"); + goto _fail_timer_3; + } + #endif + + WILC_SemaphoreCreate(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + + +#ifdef SIMULATION + TransportInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* gWFiDrvHandle->bPendingConnRequest = WILC_FALSE; */ + + /*Initialize CFG WIDS Defualt Values*/ + + pstrWFIDrv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; + pstrWFIDrv->strCfgValues.scan_source = DEFAULT_SCAN; + pstrWFIDrv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.curr_tx_rate = AUTORATE; + + + #ifdef WILC_P2P + + pstrWFIDrv->u64P2p_MgmtTimeout = 0; + + #endif + + PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", + + pstrWFIDrv->strCfgValues.site_survey_enabled, pstrWFIDrv->strCfgValues.scan_source, + pstrWFIDrv->strCfgValues.active_scan_time, pstrWFIDrv->strCfgValues.passive_scan_time, + pstrWFIDrv->strCfgValues.curr_tx_rate); + + + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + /*TODO Code to setup simulation to be removed later*/ + /*Intialize configurator module*/ + s32Error = CoreConfiguratorInit(); + if (s32Error < 0) { + PRINT_ER("Failed to initialize core configurator\n"); + goto _fail_mem_; + } + +#ifdef SIMULATION + /*Initialize Simulaor*/ + CoreConfigSimulatorInit(); +#endif + + u32Intialized = 1; + clients_count++; /* increase number of created entities */ + + return s32Error; + + +_fail_mem_: + if (pstrWFIDrv != WILC_NULL) + WILC_FREE(pstrWFIDrv); +#ifdef WILC_P2P +_fail_timer_3: + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); +#endif +_fail_timer_2: + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), WILC_NULL); +_fail_timer_1: + WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), WILC_NULL); +_fail_thread_: + WILC_ThreadDestroy(&HostIFthreadHandler, WILC_NULL); +_fail_mq_: + WILC_MsgQueueDestroy(&gMsgQHostIF, WILC_NULL); +_fail_: + return s32Error; + + +} +/** + * @brief host_int_deinit + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_deinit(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /*obtain driver handle*/ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + /*if(u32Intialized == 0) + * { + * PRINT_ER("Host Interface is not initialized\n"); + * return 0; + * }*/ + + /*BugID_5348*/ + + if (pstrWFIDrv == NULL) { + PRINT_ER("pstrWFIDrv = NULL\n"); + return 0; + } + + WILC_SemaphoreAcquire(&hSemHostIntDeinit, NULL); + + terminated_handle = pstrWFIDrv; + PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count); + + /*BugID_5348*/ + /*Destroy all timers before acquiring hSemDeinitDrvHandle*/ + /*to guarantee handling all messages befor proceeding*/ + if (WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Scan timer is active \n"); + /* msleep(HOST_IF_SCAN_TIMEOUT+1000); */ + } + + if (WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + + if (WILC_TimerDestroy(&(g_hPeriodicRSSI), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + #ifdef WILC_P2P + /*Destroy Remain-onchannel Timer*/ + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + #endif + + host_int_set_wfi_drv_handler((WILC_Uint32)WILC_NULL); + WILC_SemaphoreAcquire(&hSemDeinitDrvHandle, NULL); + + + /*Calling the CFG80211 scan done function with the abort flag set to true*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = WILC_NULL; + } + /*deinit configurator and simulator*/ +#ifdef SIMULATION + CoreConfigSimulatorDeInit(); +#endif + CoreConfiguratorDeInit(); +#ifdef SIMULATION + TransportDeInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (clients_count == 1) { + if (WILC_TimerDestroy(&g_hPeriodicRSSI, WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_EXIT; + strHostIFmsg.drvHandler = hWFIDrv; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", s32Error); + } + + WILC_SemaphoreAcquire(&hSemHostIFthrdEnd, NULL); + + + + WILC_MsgQueueDestroy(&gMsgQHostIF, WILC_NULL); + msgQ_created = 0; + + + WILC_SemaphoreDestroy(&hSemHostIFthrdEnd, NULL); + WILC_SemaphoreDestroy(&hSemDeinitDrvHandle, NULL); + + } + + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemTestDisconnectBlock), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetRSSI), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetLINKSPEED), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetCHNL), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemInactiveTime), NULL); + WILC_SemaphoreDestroy(&hWaitResponse, NULL); + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + /*Setting the gloabl driver handler with NULL*/ + u32Intialized = 0; + /* gWFiDrvHandle = NULL; */ + if (pstrWFIDrv != WILC_NULL) { + WILC_FREE(pstrWFIDrv); + /* pstrWFIDrv=WILC_NULL; */ + + } + + clients_count--; /* Decrease number of created entities */ + terminated_handle = WILC_NULL; + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return s32Error; +} + + +/** + * @brief NetworkInfoReceived + * @details function to to be called when network info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ +void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + + if (pstrWFIDrv == WILC_NULL || pstrWFIDrv == terminated_handle) { + PRINT_ER("NetworkInfo received but driver not init[%x]\n", (WILC_Uint32)pstrWFIDrv); + return; + } + + /* prepare the Asynchronous Network Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_NTWRK_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = (WILC_Uint8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", s32Error); + } + + + return; +} + +/** + * @brief GnrlAsyncInfoReceived + * @details function to be called when general Asynchronous info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 15 Mar 2012 + * @version 1.0 + */ +void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + + /*BugID_5348*/ + WILC_SemaphoreAcquire(&hSemHostIntDeinit, NULL); + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "General asynchronous info packet received \n"); + + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n"); + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == WILC_NULL) { + /* received mac status is not needed when there is no current Connect Request */ + PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n"); + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; + } + + /* prepare the General Asynchronous Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = (WILC_Uint8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", s32Error); + } + + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; +} + +/** + * @brief host_int_ScanCompleteReceived + * @details Setting scan complete received notifcation in message queue + * @param[in] WILC_Uint8* pu8Buffer, WILC_Uint32 u32Length + * @return Error code. + * @author + * @date + * @version 1.0 + */ +void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + PRINT_D(GENERIC_DBG, "Scan notification received %x\n", (WILC_Uint32)pstrWFIDrv); + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + return; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + /* prepare theScan Done message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_SCAN_COMPLETE; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + /* will be deallocated by the receiving thread */ + /*no need to send message body*/ + + /*strHostIFmsg.uniHostIFmsgBody.strScanComplete.u32Length = u32Length; + * strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer = (WILC_Uint8*)WILC_MALLOC(u32Length); + * WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer, + * pu8Buffer, u32Length); */ + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", s32Error); + } + } + + + return; + +} + +#ifdef WILC_P2P +/** + * @brief host_int_remain_on_channel + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_remain_on_channel(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID, WILC_Uint32 u32duration, WILC_Uint16 chan, tWILCpfRemainOnChanExpired RemainOnChanExpired, tWILCpfRemainOnChanReady RemainOnChanReady, void *pvUserArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the remainonchan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REMAIN_ON_CHAN; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u16Channel = chan; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanExpired = RemainOnChanExpired; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanReady = RemainOnChanReady; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pVoid = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32duration = u32duration; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_ListenStateExpired + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_ListenStateExpired(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + + /* prepare the timer fire Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_frame_register + * @details + * @param[in] Handle to wifi driver + * @return Error code. + * @author + * @date + * @version 1.0*/ +WILC_Sint32 host_int_frame_register(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16FrameType, WILC_Bool bReg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REGISTER_FRAME; + switch (u16FrameType) { + case ACTION: + PRINT_D(HOSTINF_DBG, "ACTION\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = ACTION_FRM_IDX; + break; + + case PROBE_REQ: + PRINT_D(HOSTINF_DBG, "PROBE REQ\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = PROBE_REQ_IDX; + break; + + default: + PRINT_D(HOSTINF_DBG, "Not valid frame type\n"); + break; + } + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u16FrameType = u16FrameType; + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.bReg = bReg; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} +#endif + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_add_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + * WILC_Uint32 u32DTIMPeriod,WILC_Uint32 u32HeadLen, WILC_Uint8* pu8Head, + * WILC_Uint32 u32TailLen, WILC_Uint8* pu8Tail + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + WILC_Uint32 u32DTIMPeriod, + WILC_Uint32 u32HeadLen, WILC_Uint8 *pu8Head, + WILC_Uint32 u32TailLen, WILC_Uint8 *pu8Tail) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetBeacon *pstrSetBeaconParam = &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + pstrSetBeaconParam->u32Interval = u32Interval; + pstrSetBeaconParam->u32DTIMPeriod = u32DTIMPeriod; + pstrSetBeaconParam->u32HeadLen = u32HeadLen; + pstrSetBeaconParam->pu8Head = (WILC_Uint8 *)WILC_MALLOC(u32HeadLen); + if (pstrSetBeaconParam->pu8Head == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen); + pstrSetBeaconParam->u32TailLen = u32TailLen; + + /* Bug 4599 : if tail length = 0 skip allocating & copying */ + if (u32TailLen > 0) { + pstrSetBeaconParam->pu8Tail = (WILC_Uint8 *)WILC_MALLOC(u32TailLen); + if (pstrSetBeaconParam->pu8Tail == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen); + } else { + pstrSetBeaconParam->pu8Tail = NULL; + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + if (pstrSetBeaconParam->pu8Head != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Head); + } + + if (pstrSetBeaconParam->pu8Tail != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Tail); + } + } + + return s32Error; + +} + + +/** + * @brief host_int_del_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + WILC_ERRORCHECK(s32Error); + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + +/** + * @brief host_int_add_station + * @details Setting add station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + pstrAddStationMsg->pu8Rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates); + + WILC_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + } + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief host_int_del_station + * @details Setting delete station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8MacAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelSta *pstrDelStationMsg = &strHostIFmsg.uniHostIFmsgBody.strDelStaParam; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n"); + + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + /*BugID_4795: Handling situation of deleting all stations*/ + if (pu8MacAddr == WILC_NULL) + WILC_memset(pstrDelStationMsg->au8MacAddr, 255, ETH_ALEN); + else + WILC_memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} +/** + * @brief host_int_del_allstation + * @details Setting del station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 pu8MacAddr[][ETH_ALEN]s + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 pu8MacAddr[][ETH_ALEN]) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelAllSta *pstrDelAllStationMsg = &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta; + WILC_Uint8 au8Zero_Buff[ETH_ALEN] = {0}; + WILC_Uint32 i; + WILC_Uint8 u8AssocNumb = 0; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n"); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_STA; + strHostIFmsg.drvHandler = hWFIDrv; + + /* Handling situation of deauthenticing all associated stations*/ + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) { + WILC_memcpy(pstrDelAllStationMsg->au8Sta_DelAllSta[i], pu8MacAddr[i], ETH_ALEN); + PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", pstrDelAllStationMsg->au8Sta_DelAllSta[i][0], pstrDelAllStationMsg->au8Sta_DelAllSta[i][1], pstrDelAllStationMsg->au8Sta_DelAllSta[i][2], pstrDelAllStationMsg->au8Sta_DelAllSta[i][3], pstrDelAllStationMsg->au8Sta_DelAllSta[i][4], + pstrDelAllStationMsg->au8Sta_DelAllSta[i][5]); + u8AssocNumb++; + } + } + if (!u8AssocNumb) { + PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n"); + return s32Error; + } + + pstrDelAllStationMsg->u8Num_AssocSta = u8AssocNumb; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + + } + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; + +} + +/** + * @brief host_int_edit_station + * @details Setting edit station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_EDIT_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + pstrAddStationMsg->pu8Rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates); + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} +#endif /*WILC_AP_EXTERNAL_MLME*/ +uint32_t wilc_get_chipid(uint8_t); + +WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfPowerMgmtParam *pstrPowerMgmtParam = &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam; + + PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d << \n\n", bIsEnabled); + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_POWER_MGMT; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrPowerMgmtParam->bIsEnabled = bIsEnabled; + pstrPowerMgmtParam->u32Timeout = u32Timeout; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +WILC_Sint32 host_int_setup_multicast_filter(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32count) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetMulti *pstrMulticastFilterParam = &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MULTICAST_FILTER; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrMulticastFilterParam->bIsEnabled = bIsEnabled; + pstrMulticastFilterParam->u32count = u32count; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST + +/*Bug4218: Parsing Join Param*/ +/** + * @brief host_int_ParseJoinBssParam + * @details Parse Needed Join Parameters and save it in a new JoinBssParam entry + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author zsalah + * @date + * @version 1.0**/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo) +{ + tstrJoinBssParam *pNewJoinBssParam = NULL; + WILC_Uint8 *pu8IEs; + WILC_Uint16 u16IEsLen; + WILC_Uint16 index = 0; + WILC_Uint8 suppRatesNo = 0; + WILC_Uint8 extSuppRatesNo; + WILC_Uint16 jumpOffset; + WILC_Uint8 pcipherCount; + WILC_Uint8 authCount; + WILC_Uint8 pcipherTotalCount = 0; + WILC_Uint8 authTotalCount = 0; + WILC_Uint8 i, j; + + pu8IEs = ptstrNetworkInfo->pu8IEs; + u16IEsLen = ptstrNetworkInfo->u16IEsLen; + + pNewJoinBssParam = WILC_MALLOC(sizeof(tstrJoinBssParam)); + if (pNewJoinBssParam != NULL) { + WILC_memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam)); + pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod; + pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod; + pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo; + WILC_memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6); + /*for(i=0; i<6;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->au8bssid[i]);*/ + WILC_memcpy((WILC_Uint8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1); + pNewJoinBssParam->ssidLen = ptstrNetworkInfo->u8SsidLen; + WILC_memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3); + WILC_memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3); + /*for(i=0; i<pNewJoinBssParam->ssidLen;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->ssid[i]);*/ + + /* parse supported rates: */ + while (index < u16IEsLen) { + /* supportedRates IE */ + if (pu8IEs[index] == SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Supported Rates\n"); */ + suppRatesNo = pu8IEs[index + 1]; + pNewJoinBssParam->supp_rates[0] = suppRatesNo; + index += 2; /* skipping ID and length bytes; */ + + for (i = 0; i < suppRatesNo; i++) { + pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[i+1]); */ + } + index += suppRatesNo; + continue; + } + /* Ext SupportedRates IE */ + else if (pu8IEs[index] == EXT_SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Extended Supported Rates\n"); */ + /* checking if no of ext. supp and supp rates < max limit */ + extSuppRatesNo = pu8IEs[index + 1]; + if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo)) + pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED; + else + pNewJoinBssParam->supp_rates[0] += extSuppRatesNo; + index += 2; + /* pNewJoinBssParam.supp_rates[0] contains now old number not the ext. no */ + for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) { + pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[suppRatesNo+i+1]); */ + } + index += extSuppRatesNo; + continue; + } + /* HT Cap. IE */ + else if (pu8IEs[index] == HT_CAPABILITY_IE) { + /* if IE found set the flag */ + pNewJoinBssParam->ht_capable = BTRUE; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + /* PRINT_D(HOSTINF_DBG,"HT_CAPABALE\n"); */ + continue; + } else if ((pu8IEs[index] == WMM_IE) && /* WMM Element ID */ + (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) && + (pu8IEs[index + 4] == 0xF2) && /* OUI */ + (pu8IEs[index + 5] == 0x02) && /* OUI Type */ + ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) && /* OUI Sub Type */ + (pu8IEs[index + 7] == 0x01)) { + /* Presence of WMM Info/Param element indicates WMM capability */ + pNewJoinBssParam->wmm_cap = BTRUE; + + /* Check if Bit 7 is set indicating U-APSD capability */ + if (pu8IEs[index + 8] & (1 << 7)) { + pNewJoinBssParam->uapsd_cap = BTRUE; + } + index += pu8IEs[index + 1] + 2; + continue; + } + #ifdef WILC_P2P + else if ((pu8IEs[index] == P2P_IE) && /* P2P Element ID */ + (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) && + (pu8IEs[index + 4] == 0x9a) && /* OUI */ + (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) { /* OUI Type */ + WILC_Uint16 u16P2P_count; + pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf; + pNewJoinBssParam->u8NoaEnbaled = 1; + pNewJoinBssParam->u8Index = pu8IEs[index + 9]; + + /* Check if Bit 7 is set indicating Opss capability */ + if (pu8IEs[index + 10] & (1 << 7)) { + pNewJoinBssParam->u8OppEnable = 1; + pNewJoinBssParam->u8CtWindow = pu8IEs[index + 10]; + } else + pNewJoinBssParam->u8OppEnable = 0; + /* HOSTINF_DBG */ + PRINT_D(GENERIC_DBG, "P2P Dump \n"); + for (i = 0; i < pu8IEs[index + 7]; i++) + PRINT_D(GENERIC_DBG, " %x \n", pu8IEs[index + 9 + i]); + + pNewJoinBssParam->u8Count = pu8IEs[index + 11]; + u16P2P_count = index + 12; + + WILC_memcpy(pNewJoinBssParam->au8Duration, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8Interval, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8StartTime, pu8IEs + u16P2P_count, 4); + + index += pu8IEs[index + 1] + 2; + continue; + + } + #endif + else if ((pu8IEs[index] == RSN_IE) || + ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) && + (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) && + (pu8IEs[index + 5] == 0x01))) { + WILC_Uint16 rsnIndex = index; + /*PRINT_D(HOSTINF_DBG,"RSN IE Length:%d\n",pu8IEs[rsnIndex+1]); + * for(i=0; i<pu8IEs[rsnIndex+1]; i++) + * { + * PRINT_D(HOSTINF_DBG,"%0x ",pu8IEs[rsnIndex+2+i]); + * }*/ + if (pu8IEs[rsnIndex] == RSN_IE) { + pNewJoinBssParam->mode_802_11i = 2; + /* PRINT_D(HOSTINF_DBG,"\nRSN_IE\n"); */ + } else { /* check if rsn was previously parsed */ + if (pNewJoinBssParam->mode_802_11i == 0) + pNewJoinBssParam->mode_802_11i = 1; + /* PRINT_D(HOSTINF_DBG,"\nWPA_IE\n"); */ + rsnIndex += 4; + } + rsnIndex += 7; /* skipping id, length, version(2B) and first 3 bytes of gcipher */ + pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex]; + rsnIndex++; + /* PRINT_D(HOSTINF_DBG,"Group Policy: %0x \n",pNewJoinBssParam->rsn_grp_policy); */ + /* initialize policies with invalid values */ + + jumpOffset = pu8IEs[rsnIndex] * 4; /* total no.of bytes of pcipher field (count*4) */ + + /*parsing pairwise cipher*/ + + /* saving 3 pcipher max. */ + pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + /* PRINT_D(HOSTINF_DBG,"\npcipher:%d \n",pcipherCount); */ + for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + /* PRINT_D(HOSTINF_DBG,"PAIR policy = [%0x,%0x]\n",pNewJoinBssParam->rsn_pcip_policy[i],i); */ + } + pcipherTotalCount += pcipherCount; + rsnIndex += jumpOffset; + + jumpOffset = pu8IEs[rsnIndex] * 4; + + /*parsing AKM suite (auth_policy)*/ + /* saving 3 auth policies max. */ + authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + } + authTotalCount += authCount; + rsnIndex += jumpOffset; + /*pasring rsn cap. only if rsn IE*/ + if (pu8IEs[index] == RSN_IE) { + pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex]; + pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1]; + rsnIndex += 2; + } + pNewJoinBssParam->rsn_found = 1; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + continue; + } else + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + + } + + + } + + return (void *)pNewJoinBssParam; + +} + +void host_int_freeJoinParams(void *pJoinParams) +{ + if ((tstrJoinBssParam *)pJoinParams != NULL) + WILC_FREE((tstrJoinBssParam *)pJoinParams); + else + PRINT_ER("Unable to FREE null pointer\n"); +} +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + + +/** + * @brief host_int_addBASession + * @details Open a block Ack session with the given parameters + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author anoureldin + * @date + * @version 1.0**/ + +static int host_int_addBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID, short int BufferSize, + short int SessionTimeout, void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + pBASessionInfo->u16BufferSize = BufferSize; + pBASessionInfo->u16SessionTimeout = SessionTimeout; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_delBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; +} + +WILC_Sint32 host_int_del_All_Rx_BASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; +} + +/** + * @brief host_int_setup_ipaddress + * @details setup IP in firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_setup_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *u16ipadd, WILC_Uint8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + /* TODO: Enable This feature on softap firmware */ + return 0; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + +/** + * @brief host_int_get_ipaddress + * @details Get IP from firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *u16ipadd, WILC_Uint8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler=hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx= idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/host_interface.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/host_interface.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/*! + * @file host_interface.h + * @brief File containg host interface APIs + * @author zsalah + * @sa host_interface.c + * @date 8 March 2012 + * @version 1.0 + */ + +#ifndef HOST_INT_H +#define HOST_INT_H + +#include "coreconfigurator.h" +#include "coreconfigsimulator.h" +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ +#if 0 +#define WID_BSS_TYPE 0x0000 +#define WID_CURRENT_TX_RATE 0x0001 +#define WID_CURRENT_CHANNEL 0x0002 +#define WID_PREAMBLE 0x0003 +#define WID_STATUS 0x0005 +#define WID_SCAN_TYPE 0x0007 +#define WID_KEY_ID 0x0009 +#define WID_DTIM_PERIOD 0x0010 +#define WID_POWER_MANAGEMENT 0x000B +#define WID_AUTH_TYPE 0x000D +#define WID_SITE_SURVEY 0x000E +#define WID_DTIM_PERIOD 0x0010 +#define WID_DISCONNECT 0x0016 +#define WID_SHORT_SLOT_ALLOWED 0x001A +#define WID_START_SCAN_REQ 0x001E +#define WID_RSSI 0x001F +#define WID_JOIN_REQ 0x0020 +#define WID_11N_TXOP_PROT_DISABLE 0x00B0 +#define WID_RTS_THRESHOLD 0x1000 +#define WID_FRAG_THRESHOLD 0x1001 +#define WID_SHORT_RETRY_LIMIT 0x1002 +#define WID_LONG_RETRY_LIMIT 0x1003 +#define WID_BEACON_INTERVAL 0x1006 +#define WID_ACTIVE_SCAN_TIME 0x100C +#define WID_PASSIVE_SCAN_TIME 0x100D +#define WID_SITE_SURVEY_SCAN_TIME 0x100E +#define WID_AUTH_TIMEOUT 0x1010 +#define WID_11I_PSK 0x3008 +#define WID_SITE_SURVEY_RESULTS 0x3012 +#define WID_ADD_PTK 0x301B +#define WID_ADD_RX_GTK 0x301C +#define WID_ADD_TX_GTK 0x301D +#define WID_ADD_WEP_KEY 0x3019 +#define WID_REMOVE_WEP_KEY 0x301A +#define WID_REMOVE_KEY 0x301E +#define WID_ASSOC_REQ_INFO 0x301F +#define WID_ASSOC_RES_INFO 0x3020 +#define WID_PMKID_INFO 0x3082 +#define WID_SCAN_CHANNEL_LIST 0x4084 +#define WID_11I_MODE 0x000C +#endif +#define FAIL 0x0000 +#define SUCCESS 0x0001 + +#define IP_ALEN 4 + +#define BIT2 ((WILC_Uint32)(1 << 2)) +#define BIT1 ((WILC_Uint32)(1 << 1)) +#define BIT0 ((WILC_Uint32)(1 << 0)) + +#define AP_MODE 0x01 +#define STATION_MODE 0x02 +#define GO_MODE 0x03 +#define CLIENT_MODE 0x04 + + +#define MAX_NUM_STA 9 +#define ACTIVE_SCAN_TIME 10 +#define PASSIVE_SCAN_TIME 1200 +#define MIN_SCAN_TIME 10 +#define MAX_SCAN_TIME 1200 +#define DEFAULT_SCAN 0 +#define USER_SCAN BIT0 +#define OBSS_PERIODIC_SCAN BIT1 +#define OBSS_ONETIME_SCAN BIT2 +#define GTK_RX_KEY_BUFF_LEN 24 +#define ADDKEY 0x1 +#define REMOVEKEY 0x2 +#define DEFAULTKEY 0x4 +#define ADDKEY_AP 0x8 +#define MAX_NUM_SCANNED_NETWORKS 100 /* 30 // rachel */ +#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130 +#define MAX_NUM_PROBED_SSID 10 /*One more than the number of scanned ssids*/ +#define CHANNEL_SCAN_TIME 250 /* 250 */ + +#define TX_MIC_KEY_LEN 8 +#define RX_MIC_KEY_LEN 8 +#define PTK_KEY_LEN 16 + +#define TX_MIC_KEY_MSG_LEN 26 +#define RX_MIC_KEY_MSG_LEN 48 +#define PTK_KEY_MSG_LEN 39 + +#define PMKSA_KEY_LEN 22 +#define ETH_ALEN 6 +#define PMKID_LEN 16 +#define WILC_MAX_NUM_PMKIDS 16 +#define WILC_SUPP_MCS_SET_SIZE 16 +#define WILC_ADD_STA_LENGTH 40 /* Not including the rates field cause it has variable length*/ +#define SCAN_EVENT_DONE_ABORTED +/*****************************************************************************/ +/* Data Types */ +/*****************************************************************************/ +/* typedef unsigned char uint8; */ +/* typedef signed char int8; */ +/* typedef unsigned short uint16; */ +/* typedef unsigned long uint32; */ +/* typedef uint32 Bool; */ + +#if 0 +typedef enum {WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7} WID_TYPE_T; +#endif +typedef struct { + WILC_Uint16 cfg_wid; + WID_TYPE_T cfg_type; + WILC_Sint8 *pu8Para; +} cfg_param_t; + +typedef struct _tstrStatistics { + WILC_Uint8 u8LinkSpeed; + WILC_Sint8 s8RSSI; + WILC_Uint32 u32TxCount; + WILC_Uint32 u32RxCount; + WILC_Uint32 u32TxFailureCount; + +} tstrStatistics; + + +typedef enum { + HOST_IF_IDLE = 0, + HOST_IF_SCANNING = 1, + HOST_IF_CONNECTING = 2, + HOST_IF_WAITING_CONN_RESP = 3, + HOST_IF_CONNECTED = 4, + HOST_IF_P2P_LISTEN = 5, + HOST_IF_FORCE_32BIT = 0xFFFFFFFF +} tenuHostIFstate; + +typedef struct _tstrHostIFpmkid { + WILC_Uint8 bssid[ETH_ALEN]; + WILC_Uint8 pmkid[PMKID_LEN]; +} tstrHostIFpmkid; + +typedef struct _tstrHostIFpmkidAttr { + WILC_Uint8 numpmkid; + tstrHostIFpmkid pmkidlist[WILC_MAX_NUM_PMKIDS]; +} tstrHostIFpmkidAttr; +#if 0 +/* Scan type parameter for scan request */ +typedef enum { + PASSIVE_SCAN = 0, + ACTIVE_SCAN = 1, + NUM_SCANTYPE +} tenuScanType; + +typedef enum {SITE_SURVEY_1CH = 0, + SITE_SURVEY_ALL_CH = 1, + SITE_SURVEY_OFF = 2} SITE_SURVEY_T; +#endif +typedef enum { + AUTORATE = 0, + MBPS_1 = 1, + MBPS_2 = 2, + MBPS_5_5 = 5, + MBPS_11 = 11, + MBPS_6 = 6, + MBPS_9 = 9, + MBPS_12 = 12, + MBPS_18 = 18, + MBPS_24 = 24, + MBPS_36 = 36, + MBPS_48 = 48, + MBPS_54 = 54 +} CURRENT_TX_RATE_T; + +typedef struct { + WILC_Uint32 u32SetCfgFlag; + WILC_Uint8 ht_enable; + WILC_Uint8 bss_type; + WILC_Uint8 auth_type; + WILC_Uint16 auth_timeout; + WILC_Uint8 power_mgmt_mode; + WILC_Uint16 short_retry_limit; + WILC_Uint16 long_retry_limit; + WILC_Uint16 frag_threshold; + WILC_Uint16 rts_threshold; + WILC_Uint16 preamble_type; + WILC_Uint8 short_slot_allowed; + WILC_Uint8 txop_prot_disabled; + WILC_Uint16 beacon_interval; + WILC_Uint16 dtim_period; + SITE_SURVEY_T site_survey_enabled; + WILC_Uint16 site_survey_scan_time; + WILC_Uint8 scan_source; + WILC_Uint16 active_scan_time; + WILC_Uint16 passive_scan_time; + CURRENT_TX_RATE_T curr_tx_rate; + +} tstrCfgParamVal; + +typedef enum { + RETRY_SHORT = 1 << 0, + RETRY_LONG = 1 << 1, + FRAG_THRESHOLD = 1 << 2, + RTS_THRESHOLD = 1 << 3, + BSS_TYPE = 1 << 4, + AUTH_TYPE = 1 << 5, + AUTHEN_TIMEOUT = 1 << 6, + POWER_MANAGEMENT = 1 << 7, + PREAMBLE = 1 << 8, + SHORT_SLOT_ALLOWED = 1 << 9, + TXOP_PROT_DISABLE = 1 << 10, + BEACON_INTERVAL = 1 << 11, + DTIM_PERIOD = 1 << 12, + SITE_SURVEY = 1 << 13, + SITE_SURVEY_SCAN_TIME = 1 << 14, + ACTIVE_SCANTIME = 1 << 15, + PASSIVE_SCANTIME = 1 << 16, + CURRENT_TX_RATE = 1 << 17, + HT_ENABLE = 1 << 18, +} tenuCfgParam; + +typedef struct { + WILC_Uint8 au8bssid[6]; + WILC_Sint8 s8rssi; +} tstrFoundNetworkInfo; + +typedef enum {SCAN_EVENT_NETWORK_FOUND = 0, + SCAN_EVENT_DONE = 1, + SCAN_EVENT_ABORTED = 2, + SCAN_EVENT_FORCE_32BIT = 0xFFFFFFFF} tenuScanEvent; + +typedef enum { + CONN_DISCONN_EVENT_CONN_RESP = 0, + CONN_DISCONN_EVENT_DISCONN_NOTIF = 1, + CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF +} tenuConnDisconnEvent; + +typedef enum { + WEP, + WPARxGtk, + /* WPATxGtk, */ + WPAPtk, + PMKSA, +} tenuKeyType; + + +/*Scan callBack function definition*/ +typedef void (*tWILCpfScanResult)(tenuScanEvent, tstrNetworkInfo *, void *, void *); + +/*Connect callBack function definition*/ +typedef void (*tWILCpfConnectResult)(tenuConnDisconnEvent, + tstrConnectInfo *, + WILC_Uint8, + tstrDisconnectNotifInfo *, + void *); + +#ifdef WILC_P2P +typedef void (*tWILCpfRemainOnChanExpired)(void *, WILC_Uint32); /*Remain on channel expiration callback function*/ +typedef void (*tWILCpfRemainOnChanReady)(void *); /*Remain on channel callback function*/ +#endif + +/* typedef WILC_Uint32 WILC_WFIDrvHandle; */ +typedef struct { + WILC_Sint32 s32Dummy; +} *WILC_WFIDrvHandle; + +/*! + * @struct tstrRcvdNetworkInfo + * @brief Structure to hold Received Asynchronous Network info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdNetworkInfo { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdNetworkInfo; + +/*BugID_4156*/ +typedef struct _tstrHiddenNetworkInfo { + WILC_Uint8 *pu8ssid; + WILC_Uint8 u8ssidlen; + +} tstrHiddenNetworkInfo; + +typedef struct _tstrHiddenNetwork { + /* MAX_SSID_LEN */ + tstrHiddenNetworkInfo *pstrHiddenNetworkInfo; + WILC_Uint8 u8ssidnum; + +} tstrHiddenNetwork; + +typedef struct { + /* Scan user call back function */ + tWILCpfScanResult pfUserScanResult; + + /* User specific parameter to be delivered through the Scan User Callback function */ + void *u32UserScanPvoid; + + WILC_Uint32 u32RcvdChCount; + tstrFoundNetworkInfo astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS]; +} tstrWILC_UsrScanReq; + +typedef struct { + WILC_Uint8 *pu8bssid; + WILC_Uint8 *pu8ssid; + WILC_Uint8 u8security; + AUTHTYPE_T tenuAuth_type; + size_t ssidLen; + WILC_Uint8 *pu8ConnReqIEs; + size_t ConnReqIEsLen; + /* Connect user call back function */ + tWILCpfConnectResult pfUserConnectResult; + WILC_Bool IsHTCapable; + /* User specific parameter to be delivered through the Connect User Callback function */ + void *u32UserConnectPvoid; +} tstrWILC_UsrConnReq; + +typedef struct { + WILC_Uint32 u32Address; +} tstrHostIfSetDrvHandler; + +typedef struct { + WILC_Uint32 u32Mode; +} tstrHostIfSetOperationMode; + +/*BugID_5077*/ +typedef struct { + WILC_Uint8 u8MacAddress[ETH_ALEN]; +} tstrHostIfSetMacAddress; + +/*BugID_5213*/ +typedef struct { + WILC_Uint8 *u8MacAddress; +} tstrHostIfGetMacAddress; + +/*BugID_5222*/ +typedef struct { + WILC_Uint8 au8Bssid[ETH_ALEN]; + WILC_Uint8 u8Ted; + WILC_Uint16 u16BufferSize; + WILC_Uint16 u16SessionTimeout; +} tstrHostIfBASessionInfo; + +#ifdef WILC_P2P +typedef struct { + WILC_Uint16 u16Channel; + WILC_Uint32 u32duration; + tWILCpfRemainOnChanExpired pRemainOnChanExpired; + tWILCpfRemainOnChanReady pRemainOnChanReady; + void *pVoid; + WILC_Uint32 u32ListenSessionID; +} tstrHostIfRemainOnChan; + +typedef struct { + + WILC_Bool bReg; + WILC_Uint16 u16FrameType; + WILC_Uint8 u8Regid; + + +} tstrHostIfRegisterFrame; + + +#define ACTION 0xD0 +#define PROBE_REQ 0x40 +#define PROBE_RESP 0x50 +#define ACTION_FRM_IDX 0 +#define PROBE_REQ_IDX 1 + + +enum p2p_listen_state { + P2P_IDLE, + P2P_LISTEN, + P2P_GRP_FORMATION +}; + +#endif +typedef struct { + /* Scan user structure */ + tstrWILC_UsrScanReq strWILC_UsrScanReq; + + /* Connect User structure */ + tstrWILC_UsrConnReq strWILC_UsrConnReq; + + #ifdef WILC_P2P + /*Remain on channel struvture*/ + tstrHostIfRemainOnChan strHostIfRemainOnChan; + WILC_Uint8 u8RemainOnChan_pendingreq; + WILC_Uint64 u64P2p_MgmtTimeout; + WILC_Uint8 u8P2PConnect; + #endif + + tenuHostIFstate enuHostIFstate; + + /* WILC_Bool bPendingConnRequest; */ + + #ifndef CONNECT_DIRECT + WILC_Uint32 u32SurveyResultsCount; + wid_site_survey_reslts_s astrSurveyResults[MAX_NUM_SCANNED_NETWORKS]; + #endif + + WILC_Uint8 au8AssociatedBSSID[ETH_ALEN]; + tstrCfgParamVal strCfgValues; +/* semaphores */ + WILC_SemaphoreHandle gtOsCfgValuesSem; + WILC_SemaphoreHandle hSemTestKeyBlock; + + WILC_SemaphoreHandle hSemTestDisconnectBlock; + WILC_SemaphoreHandle hSemGetRSSI; + WILC_SemaphoreHandle hSemGetLINKSPEED; + WILC_SemaphoreHandle hSemGetCHNL; + WILC_SemaphoreHandle hSemInactiveTime; +/* timer handlers */ + WILC_TimerHandle hScanTimer; + WILC_TimerHandle hConnectTimer; + #ifdef WILC_P2P + WILC_TimerHandle hRemainOnChannel; + #endif + + WILC_Bool IFC_UP; +} tstrWILC_WFIDrv; + +/*! + * @enum tenuWILC_StaFlag + * @brief Used to decode the station flag set and mask in tstrWILC_AddStaParam + * @details + * @todo + * @sa tstrWILC_AddStaParam, enum nl80211_sta_flags + * @author Enumeraion's creator + * @date 12 July 2012 + * @version 1.0 Description + */ + +typedef enum { + WILC_STA_FLAG_INVALID = 0, + WILC_STA_FLAG_AUTHORIZED, /*!< station is authorized (802.1X)*/ + WILC_STA_FLAG_SHORT_PREAMBLE, /*!< station is capable of receiving frames with short barker preamble*/ + WILC_STA_FLAG_WME, /*!< station is WME/QoS capable*/ + WILC_STA_FLAG_MFP, /*!< station uses management frame protection*/ + WILC_STA_FLAG_AUTHENTICATED /*!< station is authenticated*/ +} tenuWILC_StaFlag; + +typedef struct { + WILC_Uint8 au8BSSID[ETH_ALEN]; + WILC_Uint16 u16AssocID; + WILC_Uint8 u8NumRates; + WILC_Uint8 *pu8Rates; + WILC_Bool bIsHTSupported; + WILC_Uint16 u16HTCapInfo; + WILC_Uint8 u8AmpduParams; + WILC_Uint8 au8SuppMCsSet[16]; + WILC_Uint16 u16HTExtParams; + WILC_Uint32 u32TxBeamformingCap; + WILC_Uint8 u8ASELCap; + WILC_Uint16 u16FlagsMask; /*<! Determines which of u16FlagsSet were changed>*/ + WILC_Uint16 u16FlagsSet; /*<! Decoded according to tenuWILC_StaFlag */ +} tstrWILC_AddStaParam; + +/* extern void CfgDisconnected(void* pUserVoid, WILC_Uint16 u16reason, WILC_Uint8 * ie, size_t ie_len); */ + +/*****************************************************************************/ +/* */ +/* Host Interface API */ +/* */ +/*****************************************************************************/ + +/** + * @brief removes wpa/wpa2 keys + * @details only in BSS STA mode if External Supplicant support is enabled. + * removes all WPA/WPA2 station key entries from MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_key(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8StaAddress); +/** + * @brief removes WEP key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * remove a WEP key entry from MAC HW. + * The BSS Station automatically finds the index of the entry using its + * BSS ID and removes that entry from the MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note NO need for the STA add since it is not used for processing + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_wep_key(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8Index); +/** + * @brief sets WEP deafault key + * @details Sets the index of the WEP encryption key in use, + * in the key table + * @param[in,out] handle to the wifi driver + * @param[in] key index ( 0, 1, 2, 3) + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_WEPDefaultKeyID(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8Index); + +/** + * @brief sets WEP deafault key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * @param[in] message containing WEP Key in the following format + *|---------------------------------------| + *|Key ID Value | Key Length | Key | + *|-------------|------------|------------| + | 1byte | 1byte | Key Length | + ||---------------------------------------| + | + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_sta(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx); +/** + * @brief host_int_add_wep_key_bss_ap + * @details valid only in AP mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 28 Feb 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_ap(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx, WILC_Uint8 u8mode, AUTHTYPE_T tenuAuth_type); + +/** + * @brief adds ptk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing PTK Key in the following format + *|-------------------------------------------------------------------------| + *|Sta Adress | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + *|-----------|------------|---------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + ||-------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_ptk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8Ptk, WILC_Uint8 u8PtkKeylen, + const WILC_Uint8 *mac_addr, WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode, WILC_Uint8 u8Idx); + +/** + * @brief host_int_get_inactive_time + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing inactive time + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 15 April 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_get_inactive_time(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *mac, WILC_Uint32 *pu32InactiveTime); + +/** + * @brief adds Rx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing Rx GTK Key in the following format + *|----------------------------------------------------------------------------| + *|Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + *|------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_rx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxGtk, WILC_Uint8 u8GtkKeylen, + WILC_Uint8 u8KeyIdx, WILC_Uint32 u32KeyRSClen, WILC_Uint8 *KeyRSC, + WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode); + + +/** + * @brief adds Tx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing Tx GTK Key in the following format + *|----------------------------------------------------| + | KeyID | Key Length | Temporal Key | Tx Michael Key | + ||-------|------------|--------------|----------------| + ||1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_tx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8KeyLen, WILC_Uint8 *pu8TxGtk, WILC_Uint8 u8KeyIdx); + +/** + * @brief caches the pmkid + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver + * @param[in] message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_pmkid_info(WILC_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr *pu8PmkidInfoArray); +/** + * @brief gets the cached the pmkid info + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver, + * + * message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @param[in] + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_pmkid_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PmkidInfoArray, + WILC_Uint32 u32PmkidInfoLen); + +/** + * @brief sets the pass phrase + * @details AP/STA mode. This function gives the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * @param[in] String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PassPhrase, + WILC_Uint8 u8Psklength); +/** + * @brief gets the pass phrase + * @details AP/STA mode. This function gets the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 *pu8PassPhrase, WILC_Uint8 u8Psklength); + +/** + * @brief gets mac address + * @details + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 19 April 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress); + +/** + * @brief sets mac address + * @details + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 16 July 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress); + +/** + * @brief wait until msg q is empty + * @details + * @param[in,out] + * + * @return Error code indicating success/failure + * @note + * @author asobhy + * @date 19 march 2014 + * @version 1.0 + */ +WILC_Sint32 host_int_wait_msg_queue_idle(void); + +/** + * @brief gets the site survey results + * @details + * @param[in,out] handle to the wifi driver, + * Message containing site survey results in the + * following formate + *|---------------------------------------------------| + | MsgLength | fragNo. | MsgBodyLength | MsgBody | + ||-----------|-----------|---------------|-----------| + | 1 | 1 | 1 | 1 | + | ----------------------------------------- | ---------------- + | + ||---------------------------------------| + | Network1 | Netweork2 | ... | Network5 | + ||---------------------------------------| + | 44 | 44 | ... | 44 | + | -------------------------- | --------------------------------------- + | + ||---------------------------------------------------------------------| + | SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved | + ||------|----------|---------|----------------|-------|------|---------| + | 33 | 1 | 1 | 1 | 6 | 1 | 1 | + ||---------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +#ifndef CONNECT_DIRECT +WILC_Sint32 host_int_get_site_survey_results(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + WILC_Uint32 u32MaxSiteSrvyFragLen); +#endif + +/** + * @brief sets a start scan request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 scanSource); +/** + * @brief gets scan source of the last scan + * @details + * @param[in,out] handle to the wifi driver, + * Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ScanSource); + +/** + * @brief sets a join request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the bss descriptor + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_join_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8bssid, + WILC_Uint8 *pu8ssid, size_t ssidLen, + const WILC_Uint8 *pu8IEs, size_t IEsLen, + tWILCpfConnectResult pfConnectResult, void *pvUserArg, + WILC_Uint8 u8security, AUTHTYPE_T tenuAuth_type, + WILC_Uint8 u8channel, + void *pJoinParams); + +/** + * @brief Flush a join request parameters to FW, but actual connection + * @details The function is called in situation where WILC is connected to AP and + * required to switch to hybrid FW for P2P connection + * @param[in] handle to the wifi driver, + * @return Error code indicating success/failure + * @note + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +WILC_Sint32 host_int_flush_join_req(WILC_WFIDrvHandle hWFIDrv); + + +/** + * @brief disconnects from the currently associated network + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Reason Code of the Disconnection + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16ReasonCode); + +/** + * @brief disconnects a sta + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Association Id of the station to be disconnected + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 assoc_id); +/** + * @brief gets a Association request info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. req info in the following format + * ------------------------------------------------------------------------ + | Management Frame Format | + ||-------------------------------------------------------------------| + ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS | + ||-------------|--------|--|--|-----|----------------|----------|----| + | 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 | + ||-------------------------------------------------------------------| + | | + | Association Request Frame - Frame Body | + ||-------------------------------------------------------------------| + | Capability Information | Listen Interval | SSID | Supported Rates | + ||------------------------|-----------------|------|-----------------| + | 2 | 2 | 2-34 | 3-10 | + | --------------------------------------------------------------------- + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_req_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocReqInfo, + WILC_Uint32 u32AssocReqInfoLen); +/** + * @brief gets a Association Response info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. resp info + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_res_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocRespInfo, + WILC_Uint32 u32MaxAssocRespInfoLen, WILC_Uint32 *pu32RcvdAssocRespInfoLen); +/** + * @brief gets a Association Response info + * @details Valid only in STA mode. This function gives the RSSI + * values observed in all the channels at the time of scanning. + * The length of the field is 1 greater that the total number of + * channels supported. Byte 0 contains the number of channels while + * each of Byte N contains the observed RSSI value for the channel index N. + * @param[in,out] handle to the wifi driver, + * array of scanned channels' RSSI + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rx_power_level(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxPowerLevel, + WILC_Uint32 u32RxPowerLevelLen); + +/** + * @brief sets a channel + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the channel to be set + *|-------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_mac_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ChNum); + +/** + * @brief gets the current channel index + * @details + * @param[in,out] handle to the wifi driver, + * current channel index + *|-----------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-----------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_host_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ChNo); +/** + * @brief gets the sta rssi + * @details gets the currently maintained RSSI value for the station. + * The received signal strength value in dB. + * The range of valid values is -128 to 0. + * @param[in,out] handle to the wifi driver, + * rssi value in dB + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rssi(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8Rssi); +WILC_Sint32 host_int_get_link_speed(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8lnkspd); +/** + * @brief scans a set of channels + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan source + * Scan Type PASSIVE_SCAN = 0, + * ACTIVE_SCAN = 1 + * Channels Array + * Channels Array length + * Scan Callback function + * User Argument to be delivered back through the Scan Cllback function + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_scan(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ScanSource, + WILC_Uint8 u8ScanType, WILC_Uint8 *pu8ChnlFreqList, + WILC_Uint8 u8ChnlListLen, const WILC_Uint8 *pu8IEs, + size_t IEsLen, tWILCpfScanResult ScanResult, + void *pvUserArg, tstrHiddenNetwork *pstrHiddenNetwork); +/** + * @brief sets configuration wids values + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] WID, WID value + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_set_cfg(WILC_WFIDrvHandle hWFIDrv, tstrCfgParamVal *pstrCfgParamVal); + +/** + * @brief gets configuration wids values + * @details + * @param[in,out] handle to the wifi driver, + * WID value + * @param[in] WID, + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_get_cfg(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16WID, WILC_Uint16 *pu16WID_Value); +/*****************************************************************************/ +/* Notification Functions */ +/*****************************************************************************/ +/** + * @brief notifies host with join and leave requests + * @details This function prepares an Information frame having the + * information about a joining/leaving station. + * @param[in,out] handle to the wifi driver, + * @param[in] 6 byte Sta Adress + * Join or leave flag: + * Join = 1, + * Leave =0 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_join_leave_info_to_host + (WILC_Uint16 assocId, WILC_Uint8 *stationAddr, WILC_Bool joining); + +/** + * @brief notifies host with stations found in scan + * @details sends the beacon/probe response from scan + * @param[in,out] handle to the wifi driver, + * @param[in] Sta Address, + * Frame length, + * Rssi of the Station found + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_network_info_to_host + (WILC_Uint8 *macStartAddress, WILC_Uint16 u16RxFrameLen, WILC_Sint8 s8Rssi); + +/** + * @brief host interface initialization function + * @details + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_init(WILC_WFIDrvHandle *phWFIDrv); + +/** + * @brief host interface initialization function + * @details + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_deinit(WILC_WFIDrvHandle hWFIDrv); + + +/*! + * @fn WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv,WILC_Uint8 u8Index) + * @brief Sends a beacon to the firmware to be transmitted over the air + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] u32Interval Beacon Interval. Period between two successive beacons on air + * @param[in] u32DTIMPeriod DTIM Period. Indicates how many Beacon frames + * (including the current frame) appear before the next DTIM + * @param[in] u32Headlen Length of the head buffer in bytes + * @param[in] pu8Head Pointer to the beacon's head buffer. Beacon's head + * is the part from the beacon's start till the TIM element, NOT including the TIM + * @param[in] u32Taillen Length of the tail buffer in bytes + * @param[in] pu8Tail Pointer to the beacon's tail buffer. Beacon's tail + * starts just after the TIM inormation element + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 Julys 2012 + * @version 1.0 Description + * + */ +WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + WILC_Uint32 u32DTIMPeriod, + WILC_Uint32 u32HeadLen, WILC_Uint8 *pu8Head, + WILC_Uint32 u32TailLen, WILC_Uint8 *pu8tail); + + +/*! + * @fn WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv) + * @brief Removes the beacon and stops trawilctting it over the air + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 Julys 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv); + +/*! + * @fn WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam strStaParams) + * @brief Notifies the firmware with a new associated stations + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pstrStaParams Station's parameters + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 12 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams); + +/*! + * @fn WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8MacAddr) + * @brief Deauthenticates clients when group is terminating + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pu8MacAddr Station's mac address + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Mai Daftedar + * @date 09 April 2014 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 pu8MacAddr[][ETH_ALEN]); + +/*! + * @fn WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8MacAddr) + * @brief Notifies the firmware with a new deleted station + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pu8MacAddr Station's mac address + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddr); + +/*! + * @fn WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam strStaParams) + * @brief Notifies the firmware with new parameters of an already associated station + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pstrStaParams Station's parameters + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams); + +/*! + * @fn WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout) + * @brief Set the power management mode to enabled or disabled + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise + * @param[in] u32Timeout A timeout value of -1 allows the driver to adjust + * the dynamic ps timeout value + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout); +/* @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise + * @param[in] u8count count of mac address entries in the filter table + * + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_setup_multicast_filter(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32count); +/** + * @brief host_int_setup_ipaddress + * @details set IP address on firmware + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_setup_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx); + + +/** + * @brief host_int_delBASession + * @details Delete single Rx BA session + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_delBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID); + +/** + * @brief host_int_delBASession + * @details Delete all Rx BA session + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_All_Rx_BASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID); + + +/** + * @brief host_int_get_ipaddress + * @details get IP address on firmware + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx); + +#ifdef WILC_P2P +/** + * @brief host_int_remain_on_channel + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_remain_on_channel(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID, WILC_Uint32 u32duration, WILC_Uint16 chan, tWILCpfRemainOnChanExpired RemainOnChanExpired, tWILCpfRemainOnChanReady RemainOnChanReady, void *pvUserArg); + +/** + * @brief host_int_ListenStateExpired + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_ListenStateExpired(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID); + +/** + * @brief host_int_frame_register + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_frame_register(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16FrameType, WILC_Bool bReg); +#endif +/** + * @brief host_int_set_wfi_drv_handler + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_set_wfi_drv_handler(WILC_Uint32 u32address); +WILC_Sint32 host_int_set_operation_mode(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32mode); + +static WILC_Sint32 Handle_ScanDone(void *drvHandler, tenuScanEvent enuEvent); + +static int host_int_addBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID, short int BufferSize, + short int SessionTimeout, void *drvHandler); + + +void host_int_freeJoinParams(void *pJoinParams); + +WILC_Sint32 host_int_get_statistics(WILC_WFIDrvHandle hWFIDrv, tstrStatistics *pstrStatistics); + +/*****************************************************************************/ +/* */ +/* EOF */ +/* */ +/*****************************************************************************/ +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/itypes.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/itypes.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/*****************************************************************************/ +/* */ +/* Ittiam 802.11 MAC SOFTWARE */ +/* */ +/* ITTIAM SYSTEMS PVT LTD, BANGALORE */ +/* COPYRIGHT(C) 2005 */ +/* */ +/* This program is proprietary to Ittiam Systems Private Limited and */ +/* is protected under Indian Copyright Law as an unpublished work. Its use */ +/* and disclosure is limited by the terms and conditions of a license */ +/* agreement. It may not be copied or otherwise reproduced or disclosed to */ +/* persons outside the licensee's organization except in accordance with the*/ +/* terms and conditions of such an agreement. All copies and */ +/* reproductions shall be the property of Ittiam Systems Private Limited and*/ +/* must bear this notice in its entirety. */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* File Name : itypes.h */ +/* */ +/* Description : This file contains all the data type definitions for */ +/* MAC implementation. */ +/* */ +/* List of Functions : None */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes */ +/* 01 05 2005 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +#ifndef ITYPES_H +#define ITYPES_H + + +/*****************************************************************************/ +/* Data Types */ +/*****************************************************************************/ + +typedef int WORD32; +typedef short WORD16; +typedef char WORD8; +typedef unsigned int UWORD32; +typedef unsigned short UWORD16; +typedef unsigned char UWORD8; + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ + +typedef enum { + BFALSE = 0, + BTRUE = 1 +} BOOL_T; + +#endif /* ITYPES_H */ Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/Kconfig =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/Kconfig @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +config WILC1000 + tristate "WILC1000 support (WiFi only)" + depends on ATMEL_SMARTCONNECT + ---help--- + This module only support IEEE 802.11n WiFi. + +choice + prompt "Memory Allocation" + depends on WILC1000 + default WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT + + config WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT + bool "Preallocate memory pool during system boot" + ---help--- + To do. + + config WILC1000_PREALLOCATE_AT_LOADING_DRIVER + bool "Preallocate memory at loading driver" + ---help--- + This choice supports static allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + during initial time. The driver will also free the buffer + by calling network device stop. + + config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY + bool "Dynamically allocate memory in real time" + ---help--- + This choice supports dynamic allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + when it is required. +endchoice + + +choice + prompt "Bus Type" + depends on WILC1000 + default WILC1000_SDIO + + config WILC1000_SDIO + bool "SDIO support" + depends on MMC + ---help--- + This module adds support for the SDIO interface of adapters using + WILC chipset. Select this if your platform is using the SDIO bus. + + config WILC1000_SPI + bool "SPI support" + ---help--- + This module adds support for the SPI interface of adapters using + WILC chipset. Select this if your platform is using the SPI bus. +endchoice + + +config WILC1000_HW_OOB_INTR + bool "Use out of band interrupt" + depends on WILC1000 && WILC1000_SDIO + default n + ---help--- + If your platform don't recognize SDIO IRQ, connect chipset external IRQ pin + and check this option. Or, Use this to get all interrupts including SDIO interrupts. + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_mon.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_mon.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/*! + * @file linux_mon.c + * @brief File Operations OS wrapper functionality + * @author mdaftedar + * @sa wilc_wfi_netdevice.h + * @date 01 MAR 2012 + * @version 1.0 + */ + +#ifndef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#include "linux_wlan_common.h" +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#endif +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +#endif +#ifdef WILC_AP_EXTERNAL_MLME +#ifdef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#endif + +struct wilc_wfi_radiotap_hdr { + struct ieee80211_radiotap_header hdr; + u8 rate; + /* u32 channel; */ +} __attribute__((packed)); + +struct wilc_wfi_radiotap_cb_hdr { + struct ieee80211_radiotap_header hdr; + u8 rate; + u8 dump; + u16 tx_flags; + /* u32 channel; */ +} __attribute__((packed)); + +extern linux_wlan_t *g_linux_wlan; + +static struct net_device *wilc_wfi_mon; /* global monitor netdev */ + +#ifdef SIMULATION +extern int WILC_WFI_Tx(struct sk_buff *skb, struct net_device *dev); +#elif USE_WIRELESS +extern int mac_xmit(struct sk_buff *skb, struct net_device *dev); +#endif + + +WILC_Uint8 srcAdd[6]; +WILC_Uint8 bssid[6]; +WILC_Uint8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +/** + * @brief WILC_WFI_monitor_rx + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ + +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/ +#define IS_MANAGMEMENT 0x100 +#define IS_MANAGMEMENT_CALLBACK 0x080 +#define IS_MGMT_STATUS_SUCCES 0x040 +#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) + +void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size) +{ + uint32_t header, pkt_offset; + struct sk_buff *skb = NULL; + struct wilc_wfi_radiotap_hdr *hdr; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + PRINT_INFO(HOSTAPD_DBG, "In monitor interface receive function\n"); + + /* struct WILC_WFI_priv *priv = netdev_priv(dev); */ + + /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ + + /* Bug 4601 */ + if (wilc_wfi_mon == NULL) + return; + + if (!netif_running(wilc_wfi_mon)) { + PRINT_INFO(HOSTAPD_DBG, "Monitor interface already RUNNING\n"); + return; + } + + /* Get WILC header */ + memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); + + /* The packet offset field conain info about what type of managment frame */ + /* we are dealing with and ack status */ + pkt_offset = GET_PKT_OFFSET(header); + + if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { + + /* hostapd callback mgmt frame */ + + skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + if (skb == NULL) { + PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); + return; + } + + memcpy(skb_put(skb, size), buff, size); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + + if (pkt_offset & IS_MGMT_STATUS_SUCCES) { + /* success */ + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; + } else { + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; + } + + } else { + + skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_hdr)); + + if (skb == NULL) { + PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); + return; + } + + /* skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); */ + /* if (skb == NULL) */ + /* return; */ + + memcpy(skb_put(skb, size), buff, size); + hdr = (struct wilc_wfi_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); + memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr)); + hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + /* hdr->hdr.it_pad = 0; */ + hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_hdr)); + PRINT_INFO(HOSTAPD_DBG, "Radiotap len %d\n", hdr->hdr.it_len); + hdr->hdr.it_present = cpu_to_le32 + (1 << IEEE80211_RADIOTAP_RATE); /* | */ + /* (1 << IEEE80211_RADIOTAP_CHANNEL)); */ + PRINT_INFO(HOSTAPD_DBG, "Presentflags %d\n", hdr->hdr.it_present); + hdr->rate = 5; /* txrate->bitrate / 5; */ + + } + +/* if(INFO || if(skb->data[9] == 0x00 || skb->data[9] == 0xb0)) + * { + * for(i=0;i<skb->len;i++) + * PRINT_INFO(HOSTAPD_DBG,"Mon RxData[%d] = %02x\n",i,skb->data[i]); + * }*/ + + + skb->dev = wilc_wfi_mon; + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + + netif_rx(skb); + + +} + +struct tx_complete_mon_data { + int size; + void *buff; +}; + +static void mgmt_tx_complete(void *priv, int status) +{ + + /* struct sk_buff *skb2; */ + /* struct wilc_wfi_radiotap_cb_hdr *cb_hdr; */ + + struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; + WILC_Uint8 *buf = pv_data->buff; + + + + if (status == 1) { + if (INFO || buf[0] == 0x10 || buf[0] == 0xb0) + PRINT_INFO(HOSTAPD_DBG, "Packet sent successfully - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); + } else { + PRINT_INFO(HOSTAPD_DBG, "Couldn't send packet - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); + } + + +/* //(skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) + * { + * skb2 = dev_alloc_skb(pv_data->size+sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * memcpy(skb_put(skb2,pv_data->size),pv_data->buff, pv_data->size); + * + * cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); + * memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION; + * + * cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * cb_hdr->hdr.it_present = cpu_to_le32( + * (1 << IEEE80211_RADIOTAP_RATE) | + * (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + * + * cb_hdr->rate = 5;//txrate->bitrate / 5; + * cb_hdr->tx_flags = 0x0004; + * + * skb2->dev = wilc_wfi_mon; + * skb_set_mac_header(skb2, 0); + * skb2->ip_summed = CHECKSUM_UNNECESSARY; + * skb2->pkt_type = PACKET_OTHERHOST; + * skb2->protocol = htons(ETH_P_802_2); + * memset(skb2->cb, 0, sizeof(skb2->cb)); + * + * netif_rx(skb2); + * }*/ + + /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ + #ifndef WILC_FULLY_HOSTING_AP + kfree(pv_data->buff); + + kfree(pv_data); + #endif +} +static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len) +{ + linux_wlan_t *nic; + struct tx_complete_mon_data *mgmt_tx = NULL; + + if (dev == NULL) { + PRINT_D(HOSTAPD_DBG, "ERROR: dev == NULL\n"); + return WILC_FAIL; + } + nic = netdev_priv(dev); + + netif_stop_queue(dev); + mgmt_tx = (struct tx_complete_mon_data *)kmalloc(sizeof(struct tx_complete_mon_data), GFP_ATOMIC); + if (mgmt_tx == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); + return WILC_FAIL; + } + + #ifdef WILC_FULLY_HOSTING_AP + /* add space for the pointer to tx_complete_mon_data */ + len += sizeof(struct tx_complete_mon_data *); + #endif + + mgmt_tx->buff = (char *)kmalloc(len, GFP_ATOMIC); + if (mgmt_tx->buff == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx buff\n"); + return WILC_FAIL; + + } + + mgmt_tx->size = len; + + #ifndef WILC_FULLY_HOSTING_AP + memcpy(mgmt_tx->buff, buf, len); + #else + memcpy(mgmt_tx->buff, buf, len - sizeof(struct tx_complete_mon_data *)); + memcpy((mgmt_tx->buff) + (len - sizeof(struct tx_complete_mon_data *)), &mgmt_tx, sizeof(struct tx_complete_mon_data *)); + + /* filter data frames to handle it's PS */ + if (filter_monitor_data_frames((mgmt_tx->buff), len) == WILC_TRUE) { + return; + } + + #endif /* WILC_FULLY_HOSTING_AP */ + + g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, mgmt_tx_complete); + + netif_wake_queue(dev); + return 0; +} + +/** + * @brief WILC_WFI_mon_xmit + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ieee80211_radiotap_header *rtap_hdr; + WILC_Uint32 rtap_len, i, ret = 0; + struct WILC_WFI_mon_priv *mon_priv; + + struct sk_buff *skb2; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + /* Bug 4601 */ + if (wilc_wfi_mon == NULL) + return WILC_FAIL; + + /* if(skb->data[3] == 0x10 || skb->data[3] == 0xb0) */ + + mon_priv = netdev_priv(wilc_wfi_mon); + + if (mon_priv == NULL) { + PRINT_ER("Monitor interface private structure is NULL\n"); + return WILC_FAIL; + } + + rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; + + rtap_len = ieee80211_get_radiotap_len(skb->data); + if (skb->len < rtap_len) { + PRINT_ER("Error in radiotap header\n"); + return -1; + } + /* skip the radiotap header */ + PRINT_INFO(HOSTAPD_DBG, "Radiotap len: %d\n", rtap_len); + + if (INFO) { + for (i = 0; i < rtap_len; i++) + PRINT_INFO(HOSTAPD_DBG, "Radiotap_hdr[%d] %02x\n", i, skb->data[i]); + } + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + + if (skb->data[0] == 0xc0) + PRINT_INFO(HOSTAPD_DBG, "%x:%x:%x:%x:%x%x\n", skb->data[4], skb->data[5], skb->data[6], skb->data[7], skb->data[8], skb->data[9]); + + if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) { + skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + memcpy(skb_put(skb2, skb->len), skb->data, skb->len); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + cb_hdr->tx_flags = 0x0004; + + skb2->dev = wilc_wfi_mon; + skb_set_mac_header(skb2, 0); + skb2->ip_summed = CHECKSUM_UNNECESSARY; + skb2->pkt_type = PACKET_OTHERHOST; + skb2->protocol = htons(ETH_P_802_2); + memset(skb2->cb, 0, sizeof(skb2->cb)); + + netif_rx(skb2); + + return 0; + } + skb->dev = mon_priv->real_ndev; + + PRINT_INFO(HOSTAPD_DBG, "Skipping the radiotap header\n"); + + + + /* actual deliver of data is device-specific, and not shown here */ + PRINT_INFO(HOSTAPD_DBG, "SKB netdevice name = %s\n", skb->dev->name); + PRINT_INFO(HOSTAPD_DBG, "MONITOR real dev name = %s\n", mon_priv->real_ndev->name); + + #ifdef SIMULATION + ret = WILC_WFI_Tx(skb, mon_priv->real_ndev); + #elif USE_WIRELESS + /* Identify if Ethernet or MAC header (data or mgmt) */ + memcpy(srcAdd, &skb->data[10], 6); + memcpy(bssid, &skb->data[16], 6); + /* if source address and bssid fields are equal>>Mac header */ + /*send it to mgmt frames handler */ + if (!(memcmp(srcAdd, bssid, 6))) { + mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len); + dev_kfree_skb(skb); + } else + ret = mac_xmit(skb, mon_priv->real_ndev); + #endif + + /* return NETDEV_TX_OK; */ + return ret; +} + +static const struct net_device_ops wilc_wfi_netdev_ops = { + .ndo_start_xmit = WILC_WFI_mon_xmit, + +}; + +#ifdef WILC_FULLY_HOSTING_AP +/* + * @brief WILC_mgm_HOSTAPD_ACK + * @details report the status of transmitted mgmt frames to HOSTAPD + * @param[in] priv : pointer to tx_complete_mon_data struct + * bStatus : status of transmission + * @author Abd Al-Rahman Diab + * @date 9 May 2013 + * @version 1.0 + */ +void WILC_mgm_HOSTAPD_ACK(void *priv, WILC_Bool bStatus) +{ + struct sk_buff *skb; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; + WILC_Uint8 *buf = pv_data->buff; + + /* len of the original frame without the added pointer at the tail */ + WILC_Uint16 u16len = (pv_data->size) - sizeof(struct tx_complete_mon_data *); + + + /*if(bStatus == 1){ + * if(INFO || buf[0] == 0x10 || buf[0] == 0xb0) + * PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",u16len,pv_data->buff); + * }else{ + * PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",u16len,pv_data->buff); + * } + */ + + /* (skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) */ + { + skb = dev_alloc_skb(u16len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + memcpy(skb_put(skb, u16len), pv_data->buff, u16len); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + + + if (WILC_TRUE == bStatus) { + /* success */ + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; + } else { + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; + } + + skb->dev = wilc_wfi_mon; + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + + netif_rx(skb); + } + + /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ + kfree(pv_data->buff); + + kfree(pv_data); + +} +#endif /* WILC_FULLY_HOSTING_AP */ + +/** + * @brief WILC_WFI_mon_setup + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +static void WILC_WFI_mon_setup(struct net_device *dev) +{ + + dev->netdev_ops = &wilc_wfi_netdev_ops; + /* dev->destructor = free_netdev; */ + PRINT_INFO(CORECONFIG_DBG, "In Ethernet setup function\n"); + ether_setup(dev); + dev->tx_queue_len = 0; + dev->type = ARPHRD_IEEE80211_RADIOTAP; + memset(dev->dev_addr, 0, ETH_ALEN); + + #ifdef USE_WIRELESS + { + /* u8 * mac_add; */ + unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x8f}; + /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ + /* mac_add = (WILC_Uint8*)WILC_MALLOC(ETH_ALEN); */ + /* status = host_int_get_MacAddress(priv->hWILCWFIDrv,mac_add); */ + /* mac_add[ETH_ALEN-1]+=1; */ + memcpy(dev->dev_addr, mac_add, ETH_ALEN); + } + #else + dev->dev_addr[0] = 0x12; + #endif + +} + +/** + * @brief WILC_WFI_init_mon_interface + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +struct net_device *WILC_WFI_init_mon_interface(char *name, struct net_device *real_dev) +{ + + + WILC_Uint32 ret = WILC_SUCCESS; + struct WILC_WFI_mon_priv *priv; + + /*If monitor interface is already initialized, return it*/ + if (wilc_wfi_mon) { + return wilc_wfi_mon; + } +#if 0 + wilc_wfi_mon = alloc_netdev(sizeof(struct WILC_WFI_mon_priv), name, WILC_WFI_mon_setup); + if (wilc_wfi_mon == NULL) { + PRINT_ER("Failed to allocate netdevice\n"); + goto failed; + } + + /* rtnl_lock(); */ + PRINT_INFO(HOSTAPD_DBG, "Monitor interface name %s\n", wilc_wfi_mon->name); + + + ret = dev_alloc_name(wilc_wfi_mon, wilc_wfi_mon->name); + if (ret < 0) + goto failed_mon; + + + priv = netdev_priv(wilc_wfi_mon); + if (priv == NULL) { + PRINT_ER("private structure is NULL\n"); + return WILC_FAIL; + } + + priv->real_ndev = real_dev; + + + ret = register_netdevice(wilc_wfi_mon); + + + if (ret < 0) { + PRINT_ER("Failed to register netdevice\n"); + goto failed_mon; + } + + + return WILC_SUCCESS; + /* rtnl_unlock(); */ + +failed: + return ret; + +failed_mon: + /* rtnl_unlock(); */ + free_netdev(wilc_wfi_mon); + return ret; +#endif + + wilc_wfi_mon = alloc_etherdev(sizeof(struct WILC_WFI_mon_priv)); + if (!wilc_wfi_mon) { + PRINT_ER("failed to allocate memory\n"); + return NULL; + + } + + wilc_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(wilc_wfi_mon->name, name, IFNAMSIZ); + wilc_wfi_mon->name[IFNAMSIZ - 1] = 0; + wilc_wfi_mon->netdev_ops = &wilc_wfi_netdev_ops; + + ret = register_netdevice(wilc_wfi_mon); + if (ret) { + PRINT_ER(" register_netdevice failed (%d)\n", ret); + return NULL; + } + priv = netdev_priv(wilc_wfi_mon); + if (priv == NULL) { + PRINT_ER("private structure is NULL\n"); + return NULL; + } + + priv->real_ndev = real_dev; + + return wilc_wfi_mon; +} + +/** + * @brief WILC_WFI_deinit_mon_interface + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +int WILC_WFI_deinit_mon_interface() +{ + bool rollback_lock = false; + + if (wilc_wfi_mon != NULL) { + PRINT_D(HOSTAPD_DBG, "In Deinit monitor interface\n"); + PRINT_D(HOSTAPD_DBG, "RTNL is being locked\n"); + if (rtnl_is_locked()) { + rtnl_unlock(); + rollback_lock = true; + } + PRINT_D(HOSTAPD_DBG, "Unregister netdev\n"); + unregister_netdev(wilc_wfi_mon); + /* free_netdev(wilc_wfi_mon); */ + + if (rollback_lock) { + rtnl_lock(); + rollback_lock = false; + } + wilc_wfi_mon = NULL; + } + return WILC_SUCCESS; + +} +#endif /* WILC_AP_EXTERNAL_MLME */ Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#include "linux_wlan_common.h" +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#ifdef USE_WIRELESS +#include "wilc_wfi_cfgoperations.h" +#endif + +#include "linux_wlan_common.h" + +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/workqueue.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <asm/gpio.h> + +#include <linux/kthread.h> +#include <linux/firmware.h> +#include <linux/delay.h> + +#include <linux/init.h> +#include <linux/netdevice.h> +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +#include <linux/inetdevice.h> +#endif +#include <linux/etherdevice.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> + +#include <linux/version.h> +#include <linux/semaphore.h> + +#ifdef WILC_SDIO +#include "linux_wlan_sdio.h" +#else +#include "linux_wlan_spi.h" +#endif + +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +#endif + +#ifdef STATIC_MACADDRESS /* brandy_0724 [[ */ +#include <linux/vmalloc.h> +#include <linux/fs.h> +struct task_struct *wilc_mac_thread; +unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2}; +#endif /* brandy_0724 ]] */ + +#if defined(CUSTOMER_PLATFORM) +/* + TODO : Write power control functions as customer platform. + */ +#else + + #define _linux_wlan_device_power_on() {} + #define _linux_wlan_device_power_off() {} + + #define _linux_wlan_device_detection() {} + #define _linux_wlan_device_removal() {} +#endif + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_Bool g_obtainingIP; +#endif +extern WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue); +extern void resolve_disconnect_aberration(void *drvHandler); +extern WILC_Uint8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +void wilc1000_wlan_deinit(linux_wlan_t *nic); +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_TimerHandle hDuringIpTimer; +#endif + +static int linux_wlan_device_power(int on_off) +{ + PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off); + + if (on_off) { + _linux_wlan_device_power_on(); + } else { + _linux_wlan_device_power_off(); + } + + return 0; +} + +static int linux_wlan_device_detection(int on_off) +{ + PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off); + +#ifdef WILC_SDIO + if (on_off) { + _linux_wlan_device_detection(); + } else { + _linux_wlan_device_removal(); + } +#endif + + return 0; +} + + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr); + +static struct notifier_block g_dev_notifier = { + .notifier_call = dev_state_ev_handler +}; +#endif + +#define wilc_wlan_deinit(nic) { if (&g_linux_wlan->oup != NULL) \ + if (g_linux_wlan->oup.wlan_cleanup != NULL) \ + g_linux_wlan->oup.wlan_cleanup(); } + + +#ifndef STA_FIRMWARE +#define STA_FIRMWARE "wifi_firmware.bin" +#endif + +#ifndef AP_FIRMWARE +#define AP_FIRMWARE "wifi_firmware_ap.bin" +#endif + +#ifndef P2P_CONCURRENCY_FIRMWARE +#define P2P_CONCURRENCY_FIRMWARE "wifi_firmware_p2p_concurrency.bin" +#endif + + + +typedef struct android_wifi_priv_cmd { + char *buf; + int used_len; + int total_len; +} android_wifi_priv_cmd; + + +#define IRQ_WAIT 1 +#define IRQ_NO_WAIT 0 +/* + * to sync between mac_close and module exit. + * don't initialize or de-initialize from init/deinitlocks + * to be initialized from module wilc_netdev_init and + * deinitialized from mdoule_exit + */ +static struct semaphore close_exit_sync; +unsigned int int_rcvdU; +unsigned int int_rcvdB; +unsigned int int_clrd; + +static int wlan_deinit_locks(linux_wlan_t *nic); +static void wlan_deinitialize_threads(linux_wlan_t *nic); +static void linux_wlan_lock(void *vp); +void linux_wlan_unlock(void *vp); +extern void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size); +extern void WILC_WFI_p2p_rx(struct net_device *dev, uint8_t *buff, uint32_t size); + + +static void *internal_alloc(uint32_t size, uint32_t flag); +static void linux_wlan_tx_complete(void *priv, int status); +void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset); +static int mac_init_fn(struct net_device *ndev); +int mac_xmit(struct sk_buff *skb, struct net_device *dev); +int mac_open(struct net_device *ndev); +int mac_close(struct net_device *ndev); +static struct net_device_stats *mac_stats(struct net_device *dev); +static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); +static void wilc_set_multicast_list(struct net_device *dev); + + + +/* + * for now - in frmw_to_linux there should be private data to be passed to it + * and this data should be pointer to net device + */ +linux_wlan_t *g_linux_wlan; +wilc_wlan_oup_t *gpstrWlanOps; +WILC_Bool bEnablePS = WILC_TRUE; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) +static const struct net_device_ops wilc_netdev_ops = { + .ndo_init = mac_init_fn, + .ndo_open = mac_open, + .ndo_stop = mac_close, + .ndo_start_xmit = mac_xmit, + .ndo_do_ioctl = mac_ioctl, + .ndo_get_stats = mac_stats, + .ndo_set_rx_mode = wilc_set_multicast_list, + +}; +#define wilc_set_netdev_ops(ndev) do { (ndev)->netdev_ops = &wilc_netdev_ops; } while (0) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) + +static const struct net_device_ops wilc_netdev_ops = { + .ndo_init = mac_init_fn, + .ndo_open = mac_open, + .ndo_stop = mac_close, + .ndo_start_xmit = mac_xmit, + .ndo_do_ioctl = mac_ioctl, + .ndo_get_stats = mac_stats, + .ndo_set_multicast_list = wilc_set_multicast_list, + +}; + +#define wilc_set_netdev_ops(ndev) do { (ndev)->netdev_ops = &wilc_netdev_ops; } while (0) + +#else + +static void wilc_set_netdev_ops(struct net_device *ndev) +{ + + ndev->init = mac_init_fn; + ndev->open = mac_open; + ndev->stop = mac_close; + ndev->hard_start_xmit = mac_xmit; + ndev->do_ioctl = mac_ioctl; + ndev->get_stats = mac_stats; + ndev->set_multicast_list = wilc_set_multicast_list, +} + +#endif +#ifdef DEBUG_MODE + +extern volatile int timeNo; + +#define DEGUG_BUFFER_LENGTH 1000 +volatile int WatchDogdebuggerCounter; +char DebugBuffer[DEGUG_BUFFER_LENGTH + 20] = {0}; +static char *ps8current = DebugBuffer; + + + +void printk_later(const char *format, ...) +{ + va_list args; + va_start (args, format); + ps8current += vsprintf (ps8current, format, args); + va_end (args); + if ((ps8current - DebugBuffer) > DEGUG_BUFFER_LENGTH) { + ps8current = DebugBuffer; + } + +} + + +void dump_logs() +{ + if (DebugBuffer[0]) { + DebugBuffer[DEGUG_BUFFER_LENGTH] = 0; + PRINT_INFO(GENERIC_DBG, "early printed\n"); + PRINT_D(GENERIC_DBG, ps8current + 1); + ps8current[1] = 0; + PRINT_INFO(GENERIC_DBG, "latest printed\n"); + PRINT_D(GENERIC_DBG, DebugBuffer); + DebugBuffer[0] = 0; + ps8current = DebugBuffer; + } +} + +void Reset_WatchDogdebugger() +{ + WatchDogdebuggerCounter = 0; +} + +static int DebuggingThreadTask(void *vp) +{ + while (1) { + while (!WatchDogdebuggerCounter) { + PRINT_D(GENERIC_DBG, "Debug Thread Running %d\n", timeNo); + WatchDogdebuggerCounter = 1; + msleep(10000); + } + dump_logs(); + WatchDogdebuggerCounter = 0; + } +} + + +#endif + + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr; + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + struct net_device *dev; + WILC_Uint8 *pIP_Add_buff; + WILC_Sint32 s32status = WILC_FAIL; + perInterface_wlan_t *nic; + WILC_Uint8 null_ip[4] = {0}; + char wlan_dev_name[5] = "wlan0"; + + if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) { + PRINT_D(GENERIC_DBG, "dev_iface = NULL\n"); + return NOTIFY_DONE; + } + + if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) { + PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n"); + return NOTIFY_DONE; + } + + dev = (struct net_device *)dev_iface->ifa_dev->dev; + if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless registerd\n"); + return NOTIFY_DONE; + } + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + if (priv == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); + return NOTIFY_DONE; + } + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + nic = netdev_priv(dev); + if (nic == NULL || pstrWFIDrv == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); + return NOTIFY_DONE; + } + + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */ + + switch (event) { + case NETDEV_UP: + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); /* tony */ + + PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n"); + + + /*If we are in station mode or client mode*/ + if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + pstrWFIDrv->IFC_UP = 1; + g_obtainingIP = WILC_FALSE; + WILC_TimerStop(&hDuringIpTimer, WILC_NULL); + PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n"); + } + + + + if (bEnablePS == WILC_TRUE) + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 1, 0); + + PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); + + pIP_Add_buff = (char *) (&(dev_iface->ifa_address)); + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d \n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); + s32status = host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + + break; + + case NETDEV_DOWN: + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); /* tony */ + + PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); + if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + pstrWFIDrv->IFC_UP = 0; + g_obtainingIP = WILC_FALSE; + } + + if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + + resolve_disconnect_aberration(pstrWFIDrv); + + + PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); + + pIP_Add_buff = null_ip; + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d \n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); + + s32status = host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + + break; + + default: + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); /* tony */ + PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event); + + break; + } + + return NOTIFY_DONE; + +} +#endif + +/* + * Interrupt initialization and handling functions + */ + +void linux_wlan_enable_irq(void) +{ + +#if (RX_BH_TYPE != RX_BH_THREADED_IRQ) +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + PRINT_D(INT_DBG, "Enabling IRQ ...\n"); + enable_irq(g_linux_wlan->dev_irq_num); +#endif +#endif +} + +void linux_wlan_disable_irq(int wait) +{ +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + if (wait) { + PRINT_D(INT_DBG, "Disabling IRQ ...\n"); + disable_irq(g_linux_wlan->dev_irq_num); + } else { + PRINT_D(INT_DBG, "Disabling IRQ ...\n"); + disable_irq_nosync(g_linux_wlan->dev_irq_num); + } +#endif +} + +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) +static irqreturn_t isr_uh_routine(int irq, void *user_data) +{ + + + int_rcvdU++; +#if (RX_BH_TYPE != RX_BH_THREADED_IRQ) + linux_wlan_disable_irq(IRQ_NO_WAIT); +#endif + PRINT_D(INT_DBG, "Interrupt received UH\n"); + + /*While mac is closing cacncel the handling of any interrupts received*/ + if (g_linux_wlan->close) { + PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n"); + #if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; + #else + return IRQ_NONE; + #endif + + } +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + schedule_work(&g_linux_wlan->rx_work_queue); + return IRQ_HANDLED; +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_unlock(&g_linux_wlan->rx_sem); + return IRQ_HANDLED; +#elif (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_WAKE_THREAD; +#endif + +} +#endif + +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE || RX_BH_TYPE == RX_BH_THREADED_IRQ) + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) +irqreturn_t isr_bh_routine(int irq, void *userdata) +{ + linux_wlan_t *nic; + nic = (linux_wlan_t *)userdata; +#else +static void isr_bh_routine(struct work_struct *work) +{ + perInterface_wlan_t *nic; + nic = (perInterface_wlan_t *)container_of(work, linux_wlan_t, rx_work_queue); +#endif + + /*While mac is closing cacncel the handling of any interrupts received*/ + if (g_linux_wlan->close) { + PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n"); + #if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; + #else + return; + #endif + + + + } + + int_rcvdB++; + PRINT_D(INT_DBG, "Interrupt received BH\n"); + if (g_linux_wlan->oup.wlan_handle_rx_isr != 0) { + g_linux_wlan->oup.wlan_handle_rx_isr(); + } else { + PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n"); + } + + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; +#endif +} +#elif (RX_BH_TYPE == RX_BH_KTHREAD) +static int isr_bh_routine(void *vp) +{ + linux_wlan_t *nic; + + nic = (linux_wlan_t *)vp; + + while (1) { + linux_wlan_lock(&nic->rx_sem); + if (g_linux_wlan->close) { + + while (!kthread_should_stop()) + schedule(); + + break; + } + int_rcvdB++; + PRINT_D(INT_DBG, "Interrupt received BH\n"); + if (g_linux_wlan->oup.wlan_handle_rx_isr != 0) { + g_linux_wlan->oup.wlan_handle_rx_isr(); + } else { + PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n"); + } + } + + return 0; +} +#endif + + +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) +static int init_irq(linux_wlan_t *p_nic) +{ + int ret = 0; + linux_wlan_t *nic = p_nic; + + /*initialize GPIO and register IRQ num*/ + /*GPIO request*/ + if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) && + (gpio_direction_input(GPIO_NUM) == 0)) { +#if defined(CUSTOMER_PLATFORM) +/* + TODO : save the registerd irq number to the private wilc context in kernel. + * + * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM); + */ +#elif defined (NM73131_0_BOARD) + nic->dev_irq_num = IRQ_WILC1000; +#elif defined (PANDA_BOARD) + gpio_export(GPIO_NUM, 1); + nic->dev_irq_num = OMAP_GPIO_IRQ(GPIO_NUM); + irq_set_irq_type(nic->dev_irq_num, IRQ_TYPE_LEVEL_LOW); +#else + nic->dev_irq_num = gpio_to_irq(GPIO_NUM); +#endif + } else { + ret = -1; + PRINT_ER("could not obtain gpio for WILC_INTR\n"); + } + + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + if ((ret != -1) && (request_threaded_irq(nic->dev_irq_num, isr_uh_routine, isr_bh_routine, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/ + "WILC_IRQ", nic)) < 0) { + +#else + /*Request IRQ*/ + if ((ret != -1) && (request_irq(nic->dev_irq_num, isr_uh_routine, + IRQF_TRIGGER_LOW, "WILC_IRQ", nic) < 0)) { + +#endif + PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); + ret = -1; + } else { + + PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n", + nic->dev_irq_num, GPIO_NUM); + } + + return ret; +} +#endif + +static void deinit_irq(linux_wlan_t *nic) +{ +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + /* Deintialize IRQ */ + if (&nic->dev_irq_num != 0) { + free_irq(nic->dev_irq_num, g_linux_wlan); + + gpio_free(GPIO_NUM); + } +#endif +} + + +/* + * OS functions + */ +static void linux_wlan_msleep(uint32_t msc) +{ + if (msc <= 4000000) { + WILC_Uint32 u32Temp = msc * 1000; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) + usleep_range(u32Temp, u32Temp); +#else + /* This is delay not sleep !!!, has to be changed*/ + msleep(msc); +#endif + } else { + msleep(msc); + } +} + +static void linux_wlan_atomic_msleep(uint32_t msc) +{ + mdelay(msc); +} +static void linux_wlan_dbg(uint8_t *buff) +{ + PRINT_D(INIT_DBG, "%d\n", *buff); +} + +static void *linux_wlan_malloc_atomic(uint32_t sz) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(sz, GFP_ATOMIC); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr); + return (void *)pntr; + +} +static void *linux_wlan_malloc(uint32_t sz) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(sz, GFP_KERNEL); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr); + return (void *)pntr; +} + +void linux_wlan_free(void *vp) +{ + if (vp != NULL) { + PRINT_D(MEM_DBG, "Freeing %p\n", vp); + kfree(vp); + } +} + + +static void *internal_alloc(uint32_t size, uint32_t flag) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(size, flag); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", size, pntr); + return (void *)pntr; +} + + +static void linux_wlan_init_lock(char *lockName, void *plock, int count) +{ + sema_init((struct semaphore *)plock, count); + PRINT_D(LOCK_DBG, "Initializing [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_lock(void *plock) +{ + /* mutex_destroy((struct mutex*)plock); */ +} + +static void linux_wlan_lock(void *vp) +{ + PRINT_D(LOCK_DBG, "Locking %p\n", vp); + if (vp != NULL) { + while (down_interruptible((struct semaphore *) vp)) + ; + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + +static int linux_wlan_lock_timeout(void *vp, WILC_Uint32 timeout) +{ + int error = -1; + PRINT_D(LOCK_DBG, "Locking %p\n", vp); + if (vp != NULL) { + error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout)); + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } + return error; +} + +void linux_wlan_unlock(void *vp) +{ + PRINT_D(LOCK_DBG, "Unlocking %p\n", vp); + if (vp != NULL) { + up((struct semaphore *)vp); + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + + +static void linux_wlan_init_mutex(char *lockName, void *plock, int count) +{ + mutex_init((struct mutex *)plock); + PRINT_D(LOCK_DBG, "Initializing mutex [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_mutex(void *plock) +{ + mutex_destroy((struct mutex *)plock); +} + +static void linux_wlan_lock_mutex(void *vp) +{ + PRINT_D(LOCK_DBG, "Locking mutex %p\n", vp); + if (vp != NULL) { + /* + * if(mutex_is_locked((struct mutex*)vp)) + * { + * //PRINT_ER("Mutex already locked - %p \n",vp); + * } + */ + mutex_lock((struct mutex *)vp); + + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + +static void linux_wlan_unlock_mutex(void *vp) +{ + PRINT_D(LOCK_DBG, "Unlocking mutex %p\n", vp); + if (vp != NULL) { + + if (mutex_is_locked((struct mutex *)vp)) { + mutex_unlock((struct mutex *)vp); + } else { + /* PRINT_ER("Mutex already unlocked - %p\n",vp); */ + } + + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + + +/*Added by Amr - BugID_4720*/ +static void linux_wlan_init_spin_lock(char *lockName, void *plock, int count) +{ + spin_lock_init((spinlock_t *)plock); + PRINT_D(SPIN_DEBUG, "Initializing mutex [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_spin_lock(void *plock) +{ + +} +static void linux_wlan_spin_lock(void *vp, unsigned long *flags) +{ + unsigned long lflags; + PRINT_D(SPIN_DEBUG, "Lock spin %p\n", vp); + if (vp != NULL) { + spin_lock_irqsave((spinlock_t *)vp, lflags); + *flags = lflags; + } else { + PRINT_ER("Failed, spin lock is NULL\n"); + } +} +static void linux_wlan_spin_unlock(void *vp, unsigned long *flags) +{ + unsigned long lflags = *flags; + PRINT_D(SPIN_DEBUG, "Unlock spin %p\n", vp); + if (vp != NULL) { + spin_unlock_irqrestore((spinlock_t *)vp, lflags); + *flags = lflags; + } else { + PRINT_ER("Failed, spin lock is NULL\n"); + } +} + +static void linux_wlan_mac_indicate(int flag) +{ + /*I have to do it that way becuase there is no mean to encapsulate device pointer + * as a parameter + */ + linux_wlan_t *pd = g_linux_wlan; + int status; + + if (flag == WILC_MAC_INDICATE_STATUS) { + pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char *)&status, 4); + if (pd->mac_status == WILC_MAC_STATUS_INIT) { + pd->mac_status = status; + linux_wlan_unlock(&pd->sync_event); + } else { + pd->mac_status = status; + } + + if (pd->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */ +#if 0 + /** + * get the mac and bssid address + **/ + PRINT_D(RX_DBG, "Calling cfg_get to get MAC_ADDR\n"); + pd->oup.wlan_cfg_get(1, WID_MAC_ADDR, 0); + PRINT_D(RX_DBG, "Calling cfg_get to get BSSID\n"); + pd->oup.wlan_cfg_get(0, WID_BSSID, 1); + + /** + * get the value + **/ + pd->oup.wlan_cfg_get_value(WID_MAC_ADDR, pd->eth_src_address, 6); + pd->oup.wlan_cfg_get_value(WID_BSSID, pd->eth_dst_address, 6); + + PRINT_D(GENERIC_DBG, "Source Address = %s", pd->eth_src_address); + PRINT_D(GENERIC_DBG, "Destiation Address = %s", pd->eth_dst_address); + + /** + * launch ndis + **/ +#endif + } + + } else if (flag == WILC_MAC_INDICATE_SCAN) { + PRINT_D(GENERIC_DBG, "Scanning ...\n"); + + } + +} + +struct net_device *GetIfHandler(uint8_t *pMacHeader) +{ + uint8_t *Bssid, *Bssid1; + int i = 0; + + Bssid = pMacHeader + 10; + Bssid1 = pMacHeader + 4; + + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) || + !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) { + return g_linux_wlan->strInterfaceInfo[i].wilc_netdev; + } + } + PRINT_INFO(INIT_DBG, "Invalide handle\n"); + for (i = 0; i < 25; i++) { + PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]); + } + Bssid = pMacHeader + 18; + Bssid1 = pMacHeader + 12; + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) || + !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) { + PRINT_D(INIT_DBG, "Ctx [%p]\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + return g_linux_wlan->strInterfaceInfo[i].wilc_netdev; + } + } + PRINT_INFO(INIT_DBG, "\n"); + return NULL; +} + +int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID) +{ + int i = 0; + int ret = -1; + + PRINT_D(INIT_DBG, "set bssid on[%p]\n", wilc_netdev); + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev == wilc_netdev) { + PRINT_D(INIT_DBG, "set bssid [%x][%x][%x]\n", pBSSID[0], pBSSID[1], pBSSID[2]); + memcpy(g_linux_wlan->strInterfaceInfo[i].aBSSID, pBSSID, 6); + ret = 0; + break; + } + } + return ret; +} + +/*BugID_5213*/ +/*Function to get number of connected interfaces*/ +int linux_wlan_get_num_conn_ifcs(void) +{ + uint8_t i = 0; + uint8_t null_bssid[6] = {0}; + uint8_t ret_val = 0; + + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (memcmp(g_linux_wlan->strInterfaceInfo[i].aBSSID, null_bssid, 6)) { + ret_val++; + } + } + return ret_val; +} + +static int linux_wlan_rxq_task(void *vp) +{ + + /* inform wilc1000_wlan_init that RXQ task is started. */ + linux_wlan_unlock(&g_linux_wlan->rxq_thread_started); + while (1) { + linux_wlan_lock(&g_linux_wlan->rxq_event); + /* wait_for_completion(&g_linux_wlan->rxq_event); */ + + if (g_linux_wlan->close) { + /*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */ + linux_wlan_unlock(&g_linux_wlan->rxq_thread_started); + + while (!kthread_should_stop()) + schedule(); + + PRINT_D(RX_DBG, " RX thread stopped\n"); + break; + } + PRINT_D(RX_DBG, "Calling wlan_handle_rx_que()\n"); + + g_linux_wlan->oup.wlan_handle_rx_que(); + } + return 0; +} + +#define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS + +static int linux_wlan_txq_task(void *vp) +{ + int ret, txq_count; + +#if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS +#define TX_BACKOFF_WEIGHT_INCR_STEP (1) +#define TX_BACKOFF_WEIGHT_DECR_STEP (1) +#define TX_BACKOFF_WEIGHT_MAX (7) +#define TX_BACKOFF_WEIGHT_MIN (0) +#define TX_BACKOFF_WEIGHT_UNIT_MS (10) + int backoff_weight = TX_BACKOFF_WEIGHT_MIN; + signed long timeout; +#endif + + /* inform wilc1000_wlan_init that TXQ task is started. */ + linux_wlan_unlock(&g_linux_wlan->txq_thread_started); + while (1) { + + PRINT_D(TX_DBG, "txq_task Taking a nap :)\n"); + linux_wlan_lock(&g_linux_wlan->txq_event); + /* wait_for_completion(&pd->txq_event); */ + PRINT_D(TX_DBG, "txq_task Who waked me up :$\n"); + + if (g_linux_wlan->close) { + /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */ + linux_wlan_unlock(&g_linux_wlan->txq_thread_started); + + while (!kthread_should_stop()) + schedule(); + + PRINT_D(TX_DBG, "TX thread stopped\n"); + break; + } + PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n"); +#if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS + g_linux_wlan->oup.wlan_handle_tx_que(); +#else + do { + ret = g_linux_wlan->oup.wlan_handle_tx_que(&txq_count); + if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) { + PRINT_D(TX_DBG, "Waking up queue\n"); + /* netif_wake_queue(pd->wilc_netdev); */ + if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[0].wilc_netdev)) + netif_wake_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev); + if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) + netif_wake_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); + } + + if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */ + timeout = msecs_to_jiffies(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight); + do { + /* Back off from sending packets for some time. */ + /* schedule_timeout will allow RX task to run and free buffers.*/ + /* set_current_state(TASK_UNINTERRUPTIBLE); */ + /* timeout = schedule_timeout(timeout); */ + msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight); + } while (/*timeout*/ 0); + backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP; + if (backoff_weight > TX_BACKOFF_WEIGHT_MAX) { + backoff_weight = TX_BACKOFF_WEIGHT_MAX; + } + } else { + if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) { + backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP; + if (backoff_weight < TX_BACKOFF_WEIGHT_MIN) { + backoff_weight = TX_BACKOFF_WEIGHT_MIN; + } + } + } + /*TODO: drop packets after a certain time/number of retry count. */ + } while (ret == WILC_TX_ERR_NO_BUF && !g_linux_wlan->close); /* retry sending packets if no more buffers in chip. */ +#endif + } + return 0; +} + +static void linux_wlan_rx_complete(void) +{ + PRINT_D(RX_DBG, "RX completed\n"); +} + +int linux_wlan_get_firmware(perInterface_wlan_t *p_nic) +{ + + perInterface_wlan_t *nic = p_nic; + int ret = 0; + const struct firmware *wilc_firmware; + char *firmware; + + + if (nic->iftype == AP_MODE) + firmware = AP_FIRMWARE; + else if (nic->iftype == STATION_MODE) + firmware = STA_FIRMWARE; + + /*BugID_5137*/ + else { + PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n"); + firmware = P2P_CONCURRENCY_FIRMWARE; + } + + + + if (nic == NULL) { + PRINT_ER("NIC is NULL\n"); + goto _fail_; + } + + if (&nic->wilc_netdev->dev == NULL) { + PRINT_ER("&nic->wilc_netdev->dev is NULL\n"); + goto _fail_; + } + + + /* the firmare should be located in /lib/firmware in + * root file system with the name specified above */ + +#ifdef WILC_SDIO + if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) { + PRINT_ER("%s - firmare not available\n", firmware); + ret = -1; + goto _fail_; + } +#else + if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) { + PRINT_ER("%s - firmare not available\n", firmware); + ret = -1; + goto _fail_; + } +#endif + g_linux_wlan->wilc_firmware = wilc_firmware; /* Bug 4703 */ + +_fail_: + + return ret; + +} + +#ifdef COMPLEMENT_BOOT +int repeat_power_cycle(perInterface_wlan_t *nic); +#endif + +static int linux_wlan_start_firmware(perInterface_wlan_t *nic) +{ + + static int timeout = 5; + int ret = 0; + /* start firmware */ + PRINT_D(INIT_DBG, "Starting Firmware ...\n"); + ret = g_linux_wlan->oup.wlan_start(); + if (ret < 0) { + PRINT_ER("Failed to start Firmware\n"); + goto _fail_; + } + + /* wait for mac ready */ + PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); + ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000); + if (ret) { +#ifdef COMPLEMENT_BOOT + + if (timeout--) { + PRINT_D(INIT_DBG, "repeat power cycle[%d]", timeout); + ret = repeat_power_cycle(nic); + } else { + timeout = 5; + ret = -1; + goto _fail_; + } +#endif + PRINT_D(INIT_DBG, "Firmware start timed out"); + goto _fail_; + } + /* + * TODO: Driver shouoldn't wait forever for firmware to get started - + * in case of timeout this should be handled properly + */ + PRINT_D(INIT_DBG, "Firmware successfully started\n"); + +_fail_: + return ret; +} +static int linux_wlan_firmware_download(linux_wlan_t *p_nic) +{ + + int ret = 0; + + if (g_linux_wlan->wilc_firmware == NULL) { + PRINT_ER("Firmware buffer is NULL\n"); + ret = -ENOBUFS; + goto _FAIL_; + } + /** + * do the firmware download + **/ + PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); + ret = g_linux_wlan->oup.wlan_firmware_download(g_linux_wlan->wilc_firmware->data, g_linux_wlan->wilc_firmware->size); + if (ret < 0) { + goto _FAIL_; + } + + /* Freeing FW buffer */ + PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); + PRINT_D(INIT_DBG, "Releasing firmware\n"); + release_firmware(g_linux_wlan->wilc_firmware); + g_linux_wlan->wilc_firmware = NULL; + + PRINT_D(INIT_DBG, "Download Succeeded \n"); + +_FAIL_: + return ret; +} + + +/* startup configuration - could be changed later using iconfig*/ +static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_nic) +{ + + unsigned char c_val[64]; + #ifndef STATIC_MACADDRESS + unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff}; + #endif + unsigned int chipid = 0; + + /*BugID_5077*/ + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + + PRINT_D(TX_DBG, "Start configuring Firmware\n"); + #ifndef STATIC_MACADDRESS + /* get_random_bytes(&mac_add[5], 1); */ + #endif + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + PRINT_D(INIT_DBG, "Host = %x\n", (WILC_Uint32)pstrWFIDrv); + + PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]); + chipid = wilc_get_chipid(0); + + + if (g_linux_wlan->oup.wlan_cfg_set == NULL) { + PRINT_D(INIT_DBG, "Null p[ointer\n"); + goto _fail_; + } + + *(int *)c_val = (WILC_Uint32)pstrWFIDrv; + + if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) + goto _fail_; + + /*to tell fw that we are going to use PC test - WILC specific*/ + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = INFRASTRUCTURE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + + /* c_val[0] = RATE_AUTO; / * bug 4275: Enable autorate and limit it to 24Mbps * / */ + c_val[0] = RATE_AUTO; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_MIXED_11B_2_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_SHORT_PREAMBLE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = AUTO_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) + goto _fail_; + +#ifdef SWITCH_LOG_TERMINAL + c_val[0] = AUTO_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0, 0)) + goto _fail_; +#endif + + c_val[0] = ACTIVE_SCAN; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = SITE_SURVEY_OFF; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0)) + goto _fail_; + + *((int *)c_val) = 0xffff; /* Never use RTS-CTS */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) + goto _fail_; + + *((int *)c_val) = 2346; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) + goto _fail_; + + /* SSID */ + /* -------------------------------------------------------------- */ + /* Configuration : String with length less than 32 bytes */ + /* Values to set : Any string with length less than 32 bytes */ + /* ( In BSS Station Set SSID to "" (null string) */ + /* to enable Broadcast SSID suppport ) */ + /* -------------------------------------------------------------- */ +#ifndef USE_WIRELESS + strcpy(c_val, "nwifi"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; +#endif + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NO_POWERSAVE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = OPEN_SYSTEM; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + /* WEP/802 11I Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : WEP Key */ + /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */ + /* In case more than 5 bytes are passed on for WEP 40 */ + /* only first 5 bytes will be used as the key */ + /* ------------------------------------------------------------------ */ + + strcpy(c_val, "123456790abcdef1234567890"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; + + /* WEP/802 11I Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */ + /* Values to set : Any string with length greater than equal to 8 bytes */ + /* and less than 64 bytes */ + /* ------------------------------------------------------------------ */ + strcpy(c_val, "12345678"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0)) + goto _fail_; + + /* IEEE802.1X Key Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : Radius Server Access Secret Key */ + /* Values to set : Any string with length greater than equal to 8 bytes */ + /* and less than 65 bytes */ + /* ------------------------------------------------------------------ */ + strcpy(c_val, "password"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; + + /* IEEE802.1X Server Address Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : Radius Server IP Address */ + /* Values to set : Any valid IP Address */ + /* ------------------------------------------------------------------ */ + c_val[0] = 192; + c_val[1] = 168; + c_val[2] = 1; + c_val[3] = 112; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) + goto _fail_; + + c_val[0] = 3; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 3; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NORMAL_ACK; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 48; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 28; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0)) + goto _fail_; + + /* Beacon Interval */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets the beacon interval value */ + /* Values to set : Any 16-bit value */ + /* -------------------------------------------------------------------- */ + + *((int *)c_val) = 100; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) + goto _fail_; + + c_val[0] = REKEY_DISABLE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0)) + goto _fail_; + + /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets the Rekey Time (s) */ + /* Values to set : 32-bit value */ + /* -------------------------------------------------------------------- */ + *((int *)c_val) = 84600; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) + goto _fail_; + + /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets Rekey Group Packet count */ + /* Values to set : 32-bit Value */ + /* -------------------------------------------------------------------- */ + *((int *)c_val) = 500; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_SELF_CTS_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* Enable N */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = HT_MIXED_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0)) + goto _fail_; + + memcpy(c_val, mac_add, 6); + + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0)) + goto _fail_; + + /** + * AP only + **/ + c_val[0] = DETECT_PROTECT_REPORT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = RTS_CTS_NONHT_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = MIMO_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 7; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* Enable N with immediate block ack. */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, (WILC_Uint32)pstrWFIDrv)) + goto _fail_; + + return 0; + +_fail_: + return -1; +} + + +/**************************/ +void wilc1000_wlan_deinit(linux_wlan_t *nic) +{ + + if (g_linux_wlan->wilc1000_initialized) { + + printk("Deinitializing wilc1000 ...\n"); + + if (nic == NULL) { + PRINT_ER("nic is NULL\n"); + return; + } + +#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + /* johnny : remove */ + PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n"); +#else + wilc_bus_set_default_speed(); +#endif + + PRINT_D(INIT_DBG, "Disabling IRQ\n"); + #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + linux_wlan_disable_irq(IRQ_WAIT); + #else + #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + + #else + linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs); + disable_sdio_interrupt(); + linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs); + #endif + #endif + + + /* not sure if the following unlocks are needed or not*/ + if (&g_linux_wlan->rxq_event != NULL) { + linux_wlan_unlock(&g_linux_wlan->rxq_event); + } + + if (&g_linux_wlan->txq_event != NULL) { + linux_wlan_unlock(&g_linux_wlan->txq_event); + } + + + #if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + /*Removing the work struct from the linux kernel workqueue*/ + if (&g_linux_wlan->rx_work_queue != NULL) + flush_work(&g_linux_wlan->rx_work_queue); + + #elif (RX_BH_TYPE == RX_BH_KTHREAD) + /* if(&nic->rx_sem != NULL) */ + /* linux_wlan_unlock(&nic->rx_sem); */ + #endif + + PRINT_D(INIT_DBG, "Deinitializing Threads\n"); + wlan_deinitialize_threads(nic); + + PRINT_D(INIT_DBG, "Deinitializing IRQ\n"); + deinit_irq(g_linux_wlan); + + + if (&g_linux_wlan->oup != NULL) { + if (g_linux_wlan->oup.wlan_stop != NULL) + g_linux_wlan->oup.wlan_stop(); + } + + PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n"); + wilc_wlan_deinit(nic); +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); + + linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs); + disable_sdio_interrupt(); + linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs); + #endif +#endif + + /*De-Initialize locks*/ + PRINT_D(INIT_DBG, "Deinitializing Locks\n"); + wlan_deinit_locks(g_linux_wlan); + + /* announce that wilc1000 is not initialized */ + g_linux_wlan->wilc1000_initialized = 0; + + PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n"); + + } else { + PRINT_D(INIT_DBG, "wilc1000 is not initialized\n"); + } + return; +} + +int wlan_init_locks(linux_wlan_t *p_nic) +{ + + PRINT_D(INIT_DBG, "Initializing Locks ...\n"); + + /*initialize mutexes*/ + linux_wlan_init_mutex("hif_lock/hif_cs", &g_linux_wlan->hif_cs, 1); + linux_wlan_init_mutex("rxq_lock/rxq_cs", &g_linux_wlan->rxq_cs, 1); + linux_wlan_init_mutex("txq_lock/txq_cs", &g_linux_wlan->txq_cs, 1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_spin_lock("txq_spin_lock/txq_cs", &g_linux_wlan->txq_spinlock, 1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_lock("txq_add_to_head_lock/txq_cs", &g_linux_wlan->txq_add_to_head_cs, 1); + + linux_wlan_init_lock("txq_wait/txq_event", &g_linux_wlan->txq_event, 0); + linux_wlan_init_lock("rxq_wait/rxq_event", &g_linux_wlan->rxq_event, 0); + + linux_wlan_init_lock("cfg_wait/cfg_event", &g_linux_wlan->cfg_event, 0); + linux_wlan_init_lock("sync_event", &g_linux_wlan->sync_event, 0); + + linux_wlan_init_lock("rxq_lock/rxq_started", &g_linux_wlan->rxq_thread_started, 0); + linux_wlan_init_lock("rxq_lock/txq_started", &g_linux_wlan->txq_thread_started, 0); + + #if (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_init_lock("BH_SEM", &g_linux_wlan->rx_sem, 0); + #endif + + return 0; +} + +static int wlan_deinit_locks(linux_wlan_t *nic) +{ + PRINT_D(INIT_DBG, "De-Initializing Locks\n"); + + if (&g_linux_wlan->hif_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->hif_cs); + + if (&g_linux_wlan->rxq_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->rxq_cs); + + if (&g_linux_wlan->txq_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->txq_cs); + + /*Added by Amr - BugID_4720*/ + if (&g_linux_wlan->txq_spinlock != NULL) + linux_wlan_deinit_spin_lock(&g_linux_wlan->txq_spinlock); + + if (&g_linux_wlan->rxq_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->rxq_event); + + if (&g_linux_wlan->txq_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_event); + + /*Added by Amr - BugID_4720*/ + if (&g_linux_wlan->txq_add_to_head_cs != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_add_to_head_cs); + + if (&g_linux_wlan->rxq_thread_started != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->rxq_thread_started); + + if (&g_linux_wlan->txq_thread_started != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_thread_started); + + if (&g_linux_wlan->cfg_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->cfg_event); + + if (&g_linux_wlan->sync_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->sync_event); + + return 0; +} +void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic) +{ + + PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); + + nwi->os_context.hif_critical_section = (void *)&g_linux_wlan->hif_cs; + nwi->os_context.os_private = (void *)nic; + nwi->os_context.tx_buffer_size = LINUX_TX_SIZE; + nwi->os_context.txq_critical_section = (void *)&g_linux_wlan->txq_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_add_to_head_critical_section = (void *)&g_linux_wlan->txq_add_to_head_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_spin_lock = (void *)&g_linux_wlan->txq_spinlock; + + nwi->os_context.txq_wait_event = (void *)&g_linux_wlan->txq_event; + +#if defined (MEMORY_STATIC) + nwi->os_context.rx_buffer_size = LINUX_RX_SIZE; +#endif + nwi->os_context.rxq_critical_section = (void *)&g_linux_wlan->rxq_cs; + nwi->os_context.rxq_wait_event = (void *)&g_linux_wlan->rxq_event; + nwi->os_context.cfg_wait_event = (void *)&g_linux_wlan->cfg_event; + + nwi->os_func.os_sleep = linux_wlan_msleep; + nwi->os_func.os_atomic_sleep = linux_wlan_atomic_msleep; + nwi->os_func.os_debug = linux_wlan_dbg; + nwi->os_func.os_malloc = linux_wlan_malloc; + nwi->os_func.os_malloc_atomic = linux_wlan_malloc_atomic; + nwi->os_func.os_free = linux_wlan_free; + nwi->os_func.os_lock = linux_wlan_lock; + nwi->os_func.os_unlock = linux_wlan_unlock; + nwi->os_func.os_wait = linux_wlan_lock_timeout; + nwi->os_func.os_signal = linux_wlan_unlock; + nwi->os_func.os_enter_cs = linux_wlan_lock_mutex; + nwi->os_func.os_leave_cs = linux_wlan_unlock_mutex; + + /*Added by Amr - BugID_4720*/ + nwi->os_func.os_spin_lock = linux_wlan_spin_lock; + nwi->os_func.os_spin_unlock = linux_wlan_spin_unlock; + +#ifdef WILC_SDIO + nwi->io_func.io_type = HIF_SDIO; + nwi->io_func.io_init = linux_sdio_init; + nwi->io_func.io_deinit = linux_sdio_deinit; + nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52; + nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53; + nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed; + nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; +#else + nwi->io_func.io_type = HIF_SPI; + nwi->io_func.io_init = linux_spi_init; + nwi->io_func.io_deinit = linux_spi_deinit; + nwi->io_func.u.spi.spi_tx = linux_spi_write; + nwi->io_func.u.spi.spi_rx = linux_spi_read; + nwi->io_func.u.spi.spi_trx = linux_spi_write_read; + nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; +#endif + + /*for now - to be revised*/ + #ifdef WILC_FULLY_HOSTING_AP + /* incase of Fully hosted AP, all non cfg pkts are processed here*/ + nwi->net_func.rx_indicate = WILC_Process_rx_frame; + #else + nwi->net_func.rx_indicate = frmw_to_linux; + #endif + nwi->net_func.rx_complete = linux_wlan_rx_complete; + nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate; +} + +int wlan_initialize_threads(perInterface_wlan_t *nic) +{ + + int ret = 0; + PRINT_D(INIT_DBG, "Initializing Threads ...\n"); + +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + /*Initialize rx work queue task*/ + INIT_WORK(&g_linux_wlan->rx_work_queue, isr_bh_routine); +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + PRINT_D(INIT_DBG, "Creating kthread for Rxq BH\n"); + g_linux_wlan->rx_bh_thread = kthread_run(isr_bh_routine, (void *)g_linux_wlan, "K_RXQ_BH"); + if (g_linux_wlan->rx_bh_thread == 0) { + PRINT_ER("couldn't create RX BH thread\n"); + ret = -ENOBUFS; + goto _fail_; + } +#endif + +#ifndef TCP_ENHANCEMENTS + /* create rx task */ + PRINT_D(INIT_DBG, "Creating kthread for reception\n"); + g_linux_wlan->rxq_thread = kthread_run(linux_wlan_rxq_task, (void *)g_linux_wlan, "K_RXQ_TASK"); + if (g_linux_wlan->rxq_thread == 0) { + PRINT_ER("couldn't create RXQ thread\n"); + ret = -ENOBUFS; + goto _fail_1; + } + + /* wait for RXQ task to start. */ + linux_wlan_lock(&g_linux_wlan->rxq_thread_started); + +#endif + + /* create tx task */ + PRINT_D(INIT_DBG, "Creating kthread for transmission\n"); + g_linux_wlan->txq_thread = kthread_run(linux_wlan_txq_task, (void *)g_linux_wlan, "K_TXQ_TASK"); + if (g_linux_wlan->txq_thread == 0) { + PRINT_ER("couldn't create TXQ thread\n"); + ret = -ENOBUFS; + goto _fail_2; + } +#ifdef DEBUG_MODE + PRINT_D(INIT_DBG, "Creating kthread for Debugging\n"); + g_linux_wlan->txq_thread = kthread_run(DebuggingThreadTask, (void *)g_linux_wlan, "DebugThread"); + if (g_linux_wlan->txq_thread == 0) { + PRINT_ER("couldn't create TXQ thread\n"); + ret = -ENOBUFS; + goto _fail_2; + } +#endif + /* wait for TXQ task to start. */ + linux_wlan_lock(&g_linux_wlan->txq_thread_started); + + return 0; + +_fail_2: + /*De-Initialize 2nd thread*/ + g_linux_wlan->close = 1; + linux_wlan_unlock(&g_linux_wlan->rxq_event); + kthread_stop(g_linux_wlan->rxq_thread); + +_fail_1: + #if (RX_BH_TYPE == RX_BH_KTHREAD) + /*De-Initialize 1st thread*/ + g_linux_wlan->close = 1; + linux_wlan_unlock(&g_linux_wlan->rx_sem); + kthread_stop(g_linux_wlan->rx_bh_thread); +_fail_: + #endif + g_linux_wlan->close = 0; + return ret; +} + +static void wlan_deinitialize_threads(linux_wlan_t *nic) +{ + + g_linux_wlan->close = 1; + PRINT_D(INIT_DBG, "Deinitializing Threads\n"); + if (&g_linux_wlan->rxq_event != NULL) + linux_wlan_unlock(&g_linux_wlan->rxq_event); + + + if (g_linux_wlan->rxq_thread != NULL) { + kthread_stop(g_linux_wlan->rxq_thread); + g_linux_wlan->rxq_thread = NULL; + } + + + if (&g_linux_wlan->txq_event != NULL) + linux_wlan_unlock(&g_linux_wlan->txq_event); + + + if (g_linux_wlan->txq_thread != NULL) { + kthread_stop(g_linux_wlan->txq_thread); + g_linux_wlan->txq_thread = NULL; + } + + #if (RX_BH_TYPE == RX_BH_KTHREAD) + if (&g_linux_wlan->rx_sem != NULL) + linux_wlan_unlock(&g_linux_wlan->rx_sem); + + if (g_linux_wlan->rx_bh_thread != NULL) { + kthread_stop(g_linux_wlan->rx_bh_thread); + g_linux_wlan->rx_bh_thread = NULL; + } + #endif +} + +#ifdef STATIC_MACADDRESS +const char *path_string[] = { + "/etc/wlan", + "/data/wlan", +}; + +static int linux_wlan_read_mac_addr(void *vp) +{ + int ret = 0; + struct file *fp = (struct file *)-ENOENT; + mm_segment_t old_fs; + loff_t pos = 0; + int index; + int array_size = sizeof(path_string) / sizeof(path_string[0]); + + /* change to KERNEL_DS address limit */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + + for (index = 0; index < array_size; index++) { + fp = filp_open(path_string[index], O_WRONLY, 0640); + if (!fp) { + ret = -1; + goto exit; + } + + /*No such file or directory */ + if (IS_ERR(fp) || !fp->f_op) { + get_random_bytes(&mac_add[3], 3); + /* open file to write */ + fp = filp_open(path_string[index], O_WRONLY | O_CREAT, 0640); + + if (!fp || IS_ERR(fp)) { + ret = -1; + continue; + } else { + /* write buf to file */ + fp->f_op->write(fp, mac_add, 6, &pos); + break; + } + } else { + /* read file to buf */ + fp->f_op->read(fp, mac_add, 6, &pos); + break; + } + } + + if (index == array_size) { + PRINT_ER("random MAC\n"); + } + +exit: + if (fp && !IS_ERR(fp)) { + filp_close(fp, NULL); + } + + set_fs(old_fs); + + return ret; +} +#endif + +#ifdef COMPLEMENT_BOOT + +extern volatile int probe; +extern uint8_t core_11b_ready(void); + +#define READY_CHECK_THRESHOLD 30 +extern void wilc_wlan_global_reset(void); +uint8_t wilc1000_prepare_11b_core(wilc_wlan_inp_t *nwi, wilc_wlan_oup_t *nwo, linux_wlan_t *nic) +{ + uint8_t trials = 0; + while ((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++)))) { + PRINT_D(INIT_DBG, "11b core not ready yet: %u\n", trials); + wilc_wlan_deinit(nic); + wilc_wlan_global_reset(); + sdio_unregister_driver(&wilc_bus); + + linux_wlan_device_detection(0); + + mdelay(100); + + linux_wlan_device_detection(1); + + sdio_register_driver(&wilc_bus); + + while (!probe) { + msleep(100); + } + probe = 0; + g_linux_wlan->wilc_sdio_func = local_sdio_func; + linux_to_wlan(nwi, nic); + wilc_wlan_init(nwi, nwo); + } + + if (READY_CHECK_THRESHOLD <= trials) + return 1; + else + return 0; + +} + +int repeat_power_cycle(perInterface_wlan_t *nic) +{ + int ret = 0; + wilc_wlan_inp_t nwi; + wilc_wlan_oup_t nwo; + sdio_unregister_driver(&wilc_bus); + + linux_wlan_device_detection(0); + linux_wlan_device_power(0); + msleep(100); + linux_wlan_device_power(1); + msleep(80); + linux_wlan_device_detection(1); + msleep(20); + + sdio_register_driver(&wilc_bus); + + /* msleep(1000); */ + while (!probe) { + msleep(100); + } + probe = 0; + g_linux_wlan->wilc_sdio_func = local_sdio_func; + linux_to_wlan(&nwi, g_linux_wlan); + ret = wilc_wlan_init(&nwi, &nwo); + + g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT; + #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + enable_sdio_interrupt(); + #endif + + if (linux_wlan_get_firmware(nic)) { + PRINT_ER("Can't get firmware \n"); + ret = -1; + goto __fail__; + } + + /*Download firmware*/ + ret = linux_wlan_firmware_download(g_linux_wlan); + if (ret < 0) { + PRINT_ER("Failed to download firmware\n"); + goto __fail__; + } + /* Start firmware*/ + ret = linux_wlan_start_firmware(nic); + if (ret < 0) { + PRINT_ER("Failed to start firmware\n"); + } +__fail__: + return ret; +} +#endif + +int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) +{ + wilc_wlan_inp_t nwi; + wilc_wlan_oup_t nwo; + perInterface_wlan_t *nic = p_nic; + int ret = 0; + + if (!g_linux_wlan->wilc1000_initialized) { + g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT; + g_linux_wlan->close = 0; + g_linux_wlan->wilc1000_initialized = 0; + + wlan_init_locks(g_linux_wlan); + +#ifdef STATIC_MACADDRESS + wilc_mac_thread = kthread_run(linux_wlan_read_mac_addr, NULL, "wilc_mac_thread"); + if (wilc_mac_thread < 0) { + PRINT_ER("couldn't create Mac addr thread\n"); + } +#endif + + linux_to_wlan(&nwi, g_linux_wlan); + + ret = wilc_wlan_init(&nwi, &nwo); + if (ret < 0) { + PRINT_ER("Initializing WILC_Wlan FAILED\n"); + ret = -EIO; + goto _fail_locks_; + } + memcpy(&g_linux_wlan->oup, &nwo, sizeof(wilc_wlan_oup_t)); + + /*Save the oup structre into global pointer*/ + gpstrWlanOps = &g_linux_wlan->oup; + + + ret = wlan_initialize_threads(nic); + if (ret < 0) { + PRINT_ER("Initializing Threads FAILED\n"); + ret = -EIO; + goto _fail_wilc_wlan_; + } + +#if (defined WILC_SDIO) && (defined COMPLEMENT_BOOT) + if (wilc1000_prepare_11b_core(&nwi, &nwo, g_linux_wlan)) { + PRINT_ER("11b Core is not ready\n"); + ret = -EIO; + goto _fail_threads_; + } +#endif + +#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + if (init_irq(g_linux_wlan)) { + PRINT_ER("couldn't initialize IRQ\n"); + ret = -EIO; + goto _fail_threads_; + } +#endif + +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + if (enable_sdio_interrupt()) { + PRINT_ER("couldn't initialize IRQ\n"); + ret = -EIO; + goto _fail_irq_init_; + } +#endif + + if (linux_wlan_get_firmware(nic)) { + PRINT_ER("Can't get firmware \n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + + /*Download firmware*/ + ret = linux_wlan_firmware_download(g_linux_wlan); + if (ret < 0) { + PRINT_ER("Failed to download firmware\n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + /* Start firmware*/ + ret = linux_wlan_start_firmware(nic); + if (ret < 0) { + PRINT_ER("Failed to start firmware\n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + wilc_bus_set_max_speed(); + + if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) { + int size; + char Firmware_ver[20]; + size = g_linux_wlan->oup.wlan_cfg_get_value( + WID_FIRMWARE_VERSION, + Firmware_ver, sizeof(Firmware_ver)); + Firmware_ver[size] = '\0'; + PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver); + } + /* Initialize firmware with default configuration */ + ret = linux_wlan_init_test_config(dev, g_linux_wlan); + + if (ret < 0) { + PRINT_ER("Failed to configure firmware\n"); + ret = -EIO; + goto _fail_fw_start_; + } + + g_linux_wlan->wilc1000_initialized = 1; + return 0; /*success*/ + + +_fail_fw_start_: + if (&g_linux_wlan->oup != NULL) { + if (g_linux_wlan->oup.wlan_stop != NULL) + g_linux_wlan->oup.wlan_stop(); + } + +_fail_irq_enable_: +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + disable_sdio_interrupt(); +#endif +_fail_irq_init_: +#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + deinit_irq(g_linux_wlan); + +#endif +_fail_threads_: + wlan_deinitialize_threads(g_linux_wlan); +_fail_wilc_wlan_: + wilc_wlan_deinit(g_linux_wlan); +_fail_locks_: + wlan_deinit_locks(g_linux_wlan); + PRINT_ER("WLAN Iinitialization FAILED\n"); + } else { + PRINT_D(INIT_DBG, "wilc1000 already initialized\n"); + } + return ret; +} + + +/* + * - this function will be called automatically by OS when module inserted. + */ + +#if !defined (NM73131_0_BOARD) +int mac_init_fn(struct net_device *ndev) +{ + + /*Why we do this !!!*/ + netif_start_queue(ndev); /* ma */ + netif_stop_queue(ndev); /* ma */ + + return 0; +} +#else +int mac_init_fn(struct net_device *ndev) +{ + + unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x00}; + /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ + memcpy(ndev->dev_addr, mac_add, 6); + + if (!is_valid_ether_addr(ndev->dev_addr)) { + PRINT_ER("Error: Wrong MAC address\n"); + return -EINVAL; + } + + return 0; +} +#endif + + +void WILC_WFI_frame_register(struct wiphy *wiphy, struct net_device *dev, + u16 frame_type, bool reg); + +/* This fn is called, when this device is setup using ifconfig */ +#if !defined (NM73131_0_BOARD) +int mac_open(struct net_device *ndev) +{ + perInterface_wlan_t *nic; + + /*BugID_5213*/ + /*No need for setting mac address here anymore,*/ + /*Just set it in init_test_config()*/ + unsigned char mac_add[ETH_ALEN] = {0}; + int status; + int ret = 0; + int i = 0; + struct WILC_WFI_priv *priv; + + nic = netdev_priv(ndev); + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); + + #ifdef USE_WIRELESS + ret = WILC_WFI_InitHostInt(ndev); + if (ret < 0) { + PRINT_ER("Failed to initialize host interface\n"); + + return ret; + } + #endif + + /*initialize platform*/ + PRINT_D(INIT_DBG, "*** re-init ***\n"); + ret = wilc1000_wlan_init(ndev, nic); + if (ret < 0) { + PRINT_ER("Failed to initialize wilc1000\n"); + WILC_WFI_DeInitHostInt(ndev); + return ret; + } + + Set_machw_change_vir_if(WILC_FALSE); + + status = host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add); + PRINT_D(INIT_DBG, "Mac address: %x:%x:%x:%x:%x:%x\n", mac_add[0], mac_add[1], mac_add[2], + mac_add[3], mac_add[4], mac_add[5]); + + /* loop through the NUM of supported devices and set the MAC address */ + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (ndev == g_linux_wlan->strInterfaceInfo[i].wilc_netdev) { + memcpy(g_linux_wlan->strInterfaceInfo[i].aSrcAddress, mac_add, ETH_ALEN); + g_linux_wlan->strInterfaceInfo[i].drvHandler = (WILC_Uint32)priv->hWILCWFIDrv; + break; + } + } + + /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ + memcpy(ndev->dev_addr, g_linux_wlan->strInterfaceInfo[i].aSrcAddress, ETH_ALEN); + + if (!is_valid_ether_addr(ndev->dev_addr)) { + PRINT_ER("Error: Wrong MAC address\n"); + ret = -EINVAL; + goto _err_; + } + + + WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev, + nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg); + WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev, + nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg); + netif_wake_queue(ndev); + g_linux_wlan->open_ifcs++; + nic->mac_opened = 1; + return 0; + +_err_: + WILC_WFI_DeInitHostInt(ndev); + wilc1000_wlan_deinit(g_linux_wlan); + return ret; +} +#else +int mac_open(struct net_device *ndev) +{ + + linux_wlan_t *nic; + nic = netdev_priv(ndev); + + /*initialize platform*/ + if (wilc1000_wlan_init(nic)) { + PRINT_ER("Failed to initialize platform\n"); + return 1; + } + /* Start the network interface queue for this device */ + PRINT_D(INIT_DBG, "Starting netifQ\n"); + netif_start_queue(ndev); +/* linux_wlan_lock(&close_exit_sync); */ + return 0; +} +#endif + +struct net_device_stats *mac_stats(struct net_device *dev) +{ + perInterface_wlan_t *nic = netdev_priv(dev); + + + return &nic->netstats; +} + +/* Setup the multicast filter */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) +static void wilc_set_multicast_list(struct net_device *dev) +{ + + struct netdev_hw_addr *ha; + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + int i = 0; + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + + if (!dev) + return; + + PRINT_D(INIT_DBG, "Setting Multicast List with count = %d. \n", dev->mc.count); + + if (dev->flags & IFF_PROMISC) { + /* Normally, we should configure the chip to retrive all packets + * but we don't wanna support this right now */ + /* TODO: add promiscuous mode support */ + PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets \n"); + return; + } + + /* If there's more addresses than we handle, get all multicast + * packets and sort them out in software. */ + if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { + PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); + /* get all multicast packets */ + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_FALSE, 0); + return; + } + + /* No multicast? Just get our own stuff */ + if ((dev->mc.count) == 0) { + PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_TRUE, 0); + return; + } + + /* Store all of the multicast addresses in the hardware filter */ + netdev_for_each_mc_addr(ha, dev) + { + WILC_memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN); + PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, + gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]); + i++; + } + + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_TRUE, (dev->mc.count)); + + return; + +} + +#else + +static void wilc_set_multicast_list(struct net_device *dev) +{ + /* BIG Warning, Beware : Uncompiled, untested... */ + struct dev_mc_list *mc_ptr; + int i = 0; + + if (!dev) + return; + + PRINT_D(INIT_DBG, "Setting Multicast List. \n"); + PRINT_D(INIT_DBG, "dev->mc_count = %d\n", dev->mc_count); + + if (dev->flags & IFF_PROMISC) { + /* Normally, we should configure the chip to retrive all packets + * but we don't wanna support this right now */ + /* TODO: add promiscuous mode support */ + PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets \n"); + return; + } + + /* If there's more addresses than we handle, get all multicast + * packets and sort them out in software. */ + if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > WILC_MULTICAST_TABLE_SIZE)) { + PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); + host_int_setup_multicast_filter((WILC_WFIDrvHandle)gWFiDrvHandle, WILC_FALSE, 0); + return; + } + + /* No multicast? Just get our own stuff */ + if (dev->mc_count == 0) { + PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); + host_int_setup_multicast_filter((WILC_WFIDrvHandle)gWFiDrvHandle, WILC_TRUE, 0); + return; + } + + /* Store all of the multicast addresses in the hardware filter */ + + for (mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, i++) { + WILC_memcpy(gau8MulticastMacAddrList[i], mc_ptr->dmi_addr, ETH_ALEN) + i++; + } + + host_int_setup_multicast_filter((WILC_WFIDrvHandle)gWFiDrvHandle, WILC_TRUE, (dev->mc_count)); + +} +#endif + +static void linux_wlan_tx_complete(void *priv, int status) +{ + + struct tx_complete_data *pv_data = (struct tx_complete_data *)priv; + if (status == 1) { + PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); + } else { + PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); + } + /* Free the SK Buffer, its work is done */ + dev_kfree_skb(pv_data->skb); + linux_wlan_free(pv_data); +} + +int mac_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + perInterface_wlan_t *nic; + struct tx_complete_data *tx_data = NULL; + int QueueCount; + char *pu8UdpBuffer; + struct iphdr *ih; + struct ethhdr *eth_h; + nic = netdev_priv(ndev); + + PRINT_D(INT_DBG, "\n========\n IntUH: %d - IntBH: %d - IntCld: %d \n========\n", int_rcvdU, int_rcvdB, int_clrd); + PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n"); + + /* Stop the network interface queue */ + if (skb->dev != ndev) { + PRINT_ER("Packet not destined to this device\n"); + return 0; + } + + tx_data = (struct tx_complete_data *)internal_alloc(sizeof(struct tx_complete_data), GFP_ATOMIC); + if (tx_data == NULL) { + PRINT_ER("Failed to allocate memory for tx_data structure\n"); + dev_kfree_skb(skb); + netif_wake_queue(ndev); + return 0; + } + + tx_data->buff = skb->data; + tx_data->size = skb->len; + tx_data->skb = skb; + + eth_h = (struct ethhdr *)(skb->data); + if (eth_h->h_proto == 0x8e88) { + PRINT_D(INIT_DBG, "EAPOL transmitted\n"); + } + + /*get source and dest ip addresses*/ + ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); + + pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); + if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68)) { + PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]); + + } + PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); + + /* Send packet to MAC HW - for now the tx_complete function will be just status + * indicator. still not sure if I need to suspend host transmission till the tx_complete + * function called or not? + * allocated buffer will be freed in tx_complete function. + */ + PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); + nic->netstats.tx_packets++; + nic->netstats.tx_bytes += tx_data->size; + tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID; + #ifndef WILC_FULLY_HOSTING_AP + QueueCount = g_linux_wlan->oup.wlan_add_to_tx_que((void *)tx_data, + tx_data->buff, + tx_data->size, + linux_wlan_tx_complete); + #else + QueueCount = WILC_Xmit_data((void *)tx_data, HOST_TO_WLAN); + #endif /* WILC_FULLY_HOSTING_AP */ + + + if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) { + netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev); + netif_stop_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); + } + + return 0; +} + + +int mac_close(struct net_device *ndev) +{ + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + tstrWILC_WFIDrv *pstrWFIDrv; + + nic = netdev_priv(ndev); + + if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) { + PRINT_ER("nic = NULL\n"); + return 0; + } + + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + + if (priv == NULL) { + PRINT_ER("priv = NULL\n"); + return 0; + } + + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + + + PRINT_D(GENERIC_DBG, "Mac close\n"); + + if (g_linux_wlan == NULL) { + PRINT_ER("g_linux_wlan = NULL\n"); + return 0; + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("pstrWFIDrv = NULL\n"); + return 0; + } + + if ((g_linux_wlan->open_ifcs) > 0) { + g_linux_wlan->open_ifcs--; + } else { + PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n"); + return 0; + } + + if (nic->wilc_netdev != NULL) { + /* Stop the network interface queue */ + netif_stop_queue(nic->wilc_netdev); + + #ifdef USE_WIRELESS + WILC_WFI_DeInitHostInt(nic->wilc_netdev); + #endif + } + + if (g_linux_wlan->open_ifcs == 0) { + PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n"); + g_linux_wlan->close = 1; + wilc1000_wlan_deinit(g_linux_wlan); + #ifdef USE_WIRELESS + #ifdef WILC_AP_EXTERNAL_MLME + WILC_WFI_deinit_mon_interface(); + #endif + #endif + } + + linux_wlan_unlock(&close_exit_sync); + nic->mac_opened = 0; + + return 0; +} + + +int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) +{ + + WILC_Uint8 *buff = NULL; + WILC_Sint8 rssi; + WILC_Uint32 size = 0, length = 0; + perInterface_wlan_t *nic; + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + + + + /* struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV */ + #ifdef USE_WIRELESS + nic = netdev_priv(ndev); + + if (!g_linux_wlan->wilc1000_initialized) + return 0; + + #endif + + switch (cmd) { + /* [[ added by tony for SIOCDEVPRIVATE */ + case SIOCDEVPRIVATE + 1: + { + android_wifi_priv_cmd priv_cmd; + + PRINT_INFO(GENERIC_DBG, "in SIOCDEVPRIVATE+1\n"); + + if (copy_from_user(&priv_cmd, req->ifr_data, sizeof(android_wifi_priv_cmd))) { + s32Error = -EFAULT; + goto done; + } + + buff = kmalloc(priv_cmd.total_len, GFP_KERNEL); + if (!buff) { + s32Error = -ENOMEM; + goto done; + } + + if (copy_from_user(buff, priv_cmd.buf, priv_cmd.total_len)) { + s32Error = -EFAULT; + goto done; + } + + PRINT_INFO(GENERIC_DBG, "%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, buff, req->ifr_name); + + if (strncasecmp(buff, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, SCAN-ACTIVE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, SCAN-PASSIVE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-START", strlen("RXFILTER-START")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-START command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-STOP", strlen("RXFILTER-STOP")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-STOP command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) { + int filter_num = *(buff + strlen("RXFILTER-ADD") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-ADD command, filter_num=%d\n", __FUNCTION__, filter_num); + } else if (strncasecmp(buff, "RXFILTER-REMOVE", strlen("RXFILTER-REMOVE")) == 0) { + int filter_num = *(buff + strlen("RXFILTER-REMOVE") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-REMOVE command, filter_num=%d\n", __FUNCTION__, filter_num); + } else if (strncasecmp(buff, "BTCOEXSCAN-START", strlen("BTCOEXSCAN-START")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-START command\n", __FUNCTION__); + } else if (strncasecmp(buff, "BTCOEXSCAN-STOP", strlen("BTCOEXSCAN-STOP")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-STOP command\n", __FUNCTION__); + } else if (strncasecmp(buff, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXMODE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "SETBAND", strlen("SETBAND")) == 0) { + uint band = *(buff + strlen("SETBAND") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, SETBAND command, band=%d\n", __FUNCTION__, band); + } else if (strncasecmp(buff, "GETBAND", strlen("GETBAND")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, GETBAND command\n", __FUNCTION__); + } else if (strncasecmp(buff, "COUNTRY", strlen("COUNTRY")) == 0) { + char *country_code = buff + strlen("COUNTRY") + 1; + PRINT_INFO(GENERIC_DBG, "%s, COUNTRY command, country_code=%s\n", __FUNCTION__, country_code); + } else { + PRINT_INFO(GENERIC_DBG, "%s, Unknown command\n", __FUNCTION__); + } + } break; + + /* ]] 2013-06-24 */ + case SIOCSIWPRIV: + { + struct iwreq *wrq = (struct iwreq *) req; /* added by tony */ + + size = wrq->u.data.length; + + if (size && wrq->u.data.pointer) { + buff = kmalloc(size, GFP_KERNEL); + if (!buff) { + s32Error = -ENOMEM; + goto done; + } + + if (copy_from_user + (buff, wrq->u.data.pointer, + wrq->u.data.length)) { + s32Error = -EFAULT; + goto done; + } + + if (strncasecmp(buff, "RSSI", length) == 0) { + + #ifdef USE_WIRELESS + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); + if (s32Error) + PRINT_ER("Failed to send get rssi param's message queue "); + #endif + PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); + + /*Rounding up the rssi negative value*/ + rssi += 5; + + snprintf(buff, size, "rssi %d", rssi); + + if (copy_to_user(wrq->u.data.pointer, buff, size)) { + PRINT_ER("%s: failed to copy data to user buffer\n", __FUNCTION__); + s32Error = -EFAULT; + goto done; + } + } + } + } + break; + + default: + { + PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd); + s32Error = -EOPNOTSUPP; + goto done; + } + } + +done: + + if (buff != NULL) { + kfree(buff); + } + + return s32Error; +} + +void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset) +{ + + unsigned int frame_len = 0; + int stats; + unsigned char *buff_to_send = NULL; + struct sk_buff *skb; + char *pu8UdpBuffer; + struct iphdr *ih; + struct net_device *wilc_netdev; + perInterface_wlan_t *nic; + + wilc_netdev = GetIfHandler(buff); + if (wilc_netdev == NULL) + return; + + buff += pkt_offset; + nic = netdev_priv(wilc_netdev); + + if (size > 0) { + + frame_len = size; + buff_to_send = buff; + + + /* Need to send the packet up to the host, allocate a skb buffer */ + skb = dev_alloc_skb(frame_len); + if (skb == NULL) { + PRINT_ER("Low memory - packet droped\n"); + return; + } + + skb_reserve(skb, (unsigned int)skb->data & 0x3); + + if (g_linux_wlan == NULL || wilc_netdev == NULL) { + PRINT_ER("wilc_netdev in g_linux_wlan is NULL"); + } + skb->dev = wilc_netdev; + + if (skb->dev == NULL) { + PRINT_ER("skb->dev is NULL\n"); + } + + /* + * for(i=0;i<40;i++) + * { + * if(i<frame_len) + * WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]); + * + * }*/ + + /* skb_put(skb, frame_len); */ + memcpy(skb_put(skb, frame_len), buff_to_send, frame_len); + + /* WILC_PRINTF("After MEM_CPY\n"); */ + + /* nic = netdev_priv(wilc_netdev); */ + +#ifdef USE_WIRELESS + /* if(nic->monitor_flag) + * { + * WILC_WFI_monitor_rx(nic->wilc_netdev,skb); + * return; + * }*/ +#endif + skb->protocol = eth_type_trans(skb, wilc_netdev); + #ifndef TCP_ENHANCEMENTS + /*get source and dest ip addresses*/ + ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); + + pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); + if (buff_to_send[35] == 67 && buff_to_send[37] == 68) { + PRINT_D(RX_DBG, "DHCP Message received\n"); + } + if (buff_to_send[12] == 0x88 && buff_to_send[13] == 0x8e) + PRINT_D(GENERIC_DBG, "eapol received\n"); + #endif + /* Send the packet to the stack by giving it to the bridge */ + nic->netstats.rx_packets++; + nic->netstats.rx_bytes += frame_len; + skb->ip_summed = CHECKSUM_UNNECESSARY; + stats = netif_rx(skb); + PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats); + } + #ifndef TCP_ENHANCEMENTS + else { + PRINT_ER("Discard sending packet with len = %d\n", size); + } + #endif +} + +void WILC_WFI_mgmt_rx(uint8_t *buff, uint32_t size) +{ + int i = 0; + perInterface_wlan_t *nic; + + /*BugID_5450*/ + /*Pass the frame on the monitor interface, if any.*/ + /*Otherwise, pass it on p2p0 netdev, if registered on it*/ + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + nic = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + if (nic->monitor_flag) { + WILC_WFI_monitor_rx(buff, size); + return; + } + } + + #ifdef WILC_P2P + nic = netdev_priv(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); /* p2p0 */ + if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) || + (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg)) { + WILC_WFI_p2p_rx(g_linux_wlan->strInterfaceInfo[1].wilc_netdev, buff, size); + } + #endif +} + +int wilc_netdev_init(void) +{ + + int i; + perInterface_wlan_t *nic; + struct net_device *ndev; + + linux_wlan_init_lock("close_exit_sync", &close_exit_sync, 0); + + /*create the common structure*/ + g_linux_wlan = (linux_wlan_t *)WILC_MALLOC(sizeof(linux_wlan_t)); + memset(g_linux_wlan, 0, sizeof(linux_wlan_t)); + + /*Reset interrupt count debug*/ + int_rcvdU = 0; + int_rcvdB = 0; + int_clrd = 0; + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + register_inetaddr_notifier(&g_dev_notifier); + #endif + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + /*allocate first ethernet device with perinterface_wlan_t as its private data*/ + ndev = alloc_etherdev(sizeof(perInterface_wlan_t)); + if (!ndev) { + PRINT_ER("Failed to allocate ethernet dev\n"); + return -1; + } + + nic = netdev_priv(ndev); + memset(nic, 0, sizeof(perInterface_wlan_t)); + + /*Name the Devices*/ + if (i == 0) { + #if defined(NM73131) /* tony, 2012-09-20 */ + strcpy(ndev->name, "wilc_eth%d"); + #elif defined(PLAT_CLM9722) /* rachel */ + strcpy(ndev->name, "eth%d"); + #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */ + strcpy(ndev->name, "wlan%d"); + #endif + } else + strcpy(ndev->name, "p2p%d"); + + nic->u8IfIdx = g_linux_wlan->u8NoIfcs; + nic->wilc_netdev = ndev; + g_linux_wlan->strInterfaceInfo[g_linux_wlan->u8NoIfcs].wilc_netdev = ndev; + g_linux_wlan->u8NoIfcs++; + wilc_set_netdev_ops(ndev); + + #ifdef USE_WIRELESS + { + struct wireless_dev *wdev; + /*Register WiFi*/ + wdev = WILC_WFI_WiphyRegister(ndev); + + #ifdef WILC_SDIO + /* set netdev, tony */ + SET_NETDEV_DEV(ndev, &local_sdio_func->dev); + #endif + + if (wdev == NULL) { + PRINT_ER("Can't register WILC Wiphy\n"); + return -1; + } + + /*linking the wireless_dev structure with the netdevice*/ + nic->wilc_netdev->ieee80211_ptr = wdev; + nic->wilc_netdev->ml_priv = nic; + wdev->netdev = nic->wilc_netdev; + nic->netstats.rx_packets = 0; + nic->netstats.tx_packets = 0; + nic->netstats.rx_bytes = 0; + nic->netstats.tx_bytes = 0; + + } + #endif + + + if (register_netdev(ndev)) { + PRINT_ER("Device couldn't be registered - %s\n", ndev->name); + return -1; /* ERROR */ + } + + nic->iftype = STATION_MODE; + nic->mac_opened = 0; + + } + + #ifndef WILC_SDIO + if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) { + PRINT_ER("Can't initialize SPI \n"); + return -1; /* ERROR */ + } + g_linux_wlan->wilc_spidev = wilc_spi_dev; + #else + g_linux_wlan->wilc_sdio_func = local_sdio_func; + #endif + + return 0; +} + + +/*The 1st function called after module inserted*/ +static int __init init_wilc_driver(void) +{ + + +#if defined (WILC_DEBUGFS) + if (wilc_debugfs_init() < 0) { + PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n"); + return -1; + } +#endif + + printk("IN INIT FUNCTION\n"); + printk("*** WILC1000 driver VERSION=[%s] FW_VER=[%s] ***\n", __DRIVER_VERSION__, __DRIVER_VERSION__); + + linux_wlan_device_power(1); + msleep(100); + linux_wlan_device_detection(1); + +#ifdef WILC_SDIO + { + int ret; + + ret = sdio_register_driver(&wilc_bus); + if (ret < 0) { + PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n"); + } + + return ret; + } +#else + PRINT_D(INIT_DBG, "Initializing netdev\n"); + if (wilc_netdev_init()) { + PRINT_ER("Couldn't initialize netdev\n"); + } + return 0; +#endif +} +late_initcall(init_wilc_driver); + +static void __exit exit_wilc_driver(void) +{ + int i = 0; + perInterface_wlan_t *nic[NUM_CONCURRENT_IFC]; + #define CLOSE_TIMEOUT (12 * 1000) + + if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL) + || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + unregister_inetaddr_notifier(&g_dev_notifier); + #endif + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + nic[i] = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + + + if ((g_linux_wlan != NULL) && g_linux_wlan->wilc_firmware != NULL) { + release_firmware(g_linux_wlan->wilc_firmware); + g_linux_wlan->wilc_firmware = NULL; + } + + + if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL) + || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) { + PRINT_D(INIT_DBG, "Waiting for mac_close ....\n"); + + if (linux_wlan_lock_timeout(&close_exit_sync, CLOSE_TIMEOUT) < 0) + PRINT_D(INIT_DBG, "Closed TimedOUT\n"); + else + PRINT_D(INIT_DBG, "mac_closed\n"); + + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + /* close all opened interfaces */ + if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev != NULL) { + if (nic[i]->mac_opened) { + mac_close(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + } + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + PRINT_D(INIT_DBG, "Unregistering netdev %p \n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + unregister_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + #ifdef USE_WIRELESS + PRINT_D(INIT_DBG, "Freeing Wiphy...\n"); + WILC_WFI_WiphyFree(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + #endif + PRINT_D(INIT_DBG, "Freeing netdev...\n"); + free_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + + +#ifdef USE_WIRELESS +#ifdef WILC_AP_EXTERNAL_MLME + /* Bug 4600 : WILC_WFI_deinit_mon_interface was already called at mac_close */ + /* WILC_WFI_deinit_mon_interface(); */ +#endif +#endif + + /* if(g_linux_wlan->open_ifcs==0) */ + { + #ifndef WILC_SDIO + PRINT_D(INIT_DBG, "SPI unregsiter...\n"); + spi_unregister_driver(&wilc_bus); + #else + PRINT_D(INIT_DBG, "SDIO unregsiter...\n"); + sdio_unregister_driver(&wilc_bus); + #endif + + linux_wlan_deinit_lock(&close_exit_sync); + if (g_linux_wlan != NULL) { + WILC_FREE(g_linux_wlan); + g_linux_wlan = NULL; + } + printk("Module_exit Done.\n"); + +#if defined (WILC_DEBUGFS) + wilc_debugfs_remove(); +#endif + + linux_wlan_device_detection(0); + linux_wlan_device_power(0); + } +} +module_exit(exit_wilc_driver); + +MODULE_LICENSE("GPL"); +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_common.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_common.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef LINUX_WLAN_COMMON_H +#define LINUX_WLAN_COMMON_H + +enum debug_region { + Generic_debug = 0, + Hostapd_debug, + Hostinf_debug, + CFG80211_debug, + Coreconfig_debug, + Interrupt_debug, + TX_debug, + RX_debug, + Lock_debug, + Tcp_enhance, + /*Added by amr - BugID_4720*/ + Spin_debug, + + Init_debug, + Bus_debug, + Mem_debug, + Firmware_debug, + COMP = 0xFFFFFFFF, +}; + +#define GENERIC_DBG (1 << Generic_debug) +#define HOSTAPD_DBG (1 << Hostapd_debug) +#define HOSTINF_DBG (1 << Hostinf_debug) +#define CORECONFIG_DBG (1 << Coreconfig_debug) +#define CFG80211_DBG (1 << CFG80211_debug) +#define INT_DBG (1 << Interrupt_debug) +#define TX_DBG (1 << TX_debug) +#define RX_DBG (1 << RX_debug) +#define LOCK_DBG (1 << Lock_debug) +#define TCP_ENH (1 << Tcp_enhance) + + +/*Added by Amr - BugID_4720*/ +#define SPIN_DEBUG (1 << Spin_debug) + +#define INIT_DBG (1 << Init_debug) +#define BUS_DBG (1 << Bus_debug) +#define MEM_DBG (1 << Mem_debug) +#define FIRM_DBG (1 << Firmware_debug) + +#if defined (WILC_DEBUGFS) +extern int wilc_debugfs_init(void); +extern void wilc_debugfs_remove(void); + +extern atomic_t REGION; +extern atomic_t DEBUG_LEVEL; + +#define DEBUG (1 << 0) +#define INFO (1 << 1) +#define WRN (1 << 2) +#define ERR (1 << 3) + +#define PRINT_D(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & DEBUG) && ((atomic_read(®ION)) & (region))) { \ + printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_INFO(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & INFO) && ((atomic_read(®ION)) & (region))) { \ + printk("INFO [%s]", __FUNCTION__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_WRN(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & WRN) && ((atomic_read(®ION)) & (region))) { \ + printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_ER(...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & ERR)) { \ + printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#else + +#define REGION (INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG) + +#define DEBUG 1 +#define INFO 0 +#define WRN 0 +#define PRINT_D(region, ...) do { if (DEBUG == 1 && ((REGION)&(region))) { \ + printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_INFO(region, ...) do { if (INFO == 1 && ((REGION)&(region))) { \ + printk("INFO [%s]", __FUNCTION__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_WRN(region, ...) do { if (WRN == 1 && ((REGION)&(region))) { \ + printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_ER(...) do { printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } while (0) +#endif + +#define FN_IN /* PRINT_D(">>> \n") */ +#define FN_OUT /* PRINT_D("<<<\n") */ + +#ifdef MEMORY_STATIC +#define LINUX_RX_SIZE (96 * 1024) +#endif +#define LINUX_TX_SIZE (64 * 1024) + + +#define WILC_MULTICAST_TABLE_SIZE 8 + +#if defined (NM73131_0_BOARD) + +#define MODALIAS "wilc_spi" +#define GPIO_NUM IRQ_WILC1000_GPIO + +#elif defined (BEAGLE_BOARD) + #define SPI_CHANNEL 4 + + #if SPI_CHANNEL == 4 + #define MODALIAS "wilc_spi4" + #define GPIO_NUM 162 + #else + #define MODALIAS "wilc_spi3" + #define GPIO_NUM 133 + #endif +#elif defined(PANDA_BOARD) + #define MODALIAS "WILC_SPI" + #define GPIO_NUM 139 +#elif defined(PLAT_WMS8304) /* rachel */ + #define MODALIAS "wilc_spi" + #define GPIO_NUM 139 +#elif defined (PLAT_RKXXXX) + #define MODALIAS "WILC_IRQ" + #define GPIO_NUM RK30_PIN3_PD2 /* RK30_PIN3_PA1 */ +/* RK30_PIN3_PD2 */ +/* RK2928_PIN1_PA7 */ + +#elif defined(CUSTOMER_PLATFORM) +/* + TODO : specify MODALIAS name and GPIO number. This is certainly necessary for SPI interface. + * + * ex) + * #define MODALIAS "WILC_SPI" + * #define GPIO_NUM 139 + */ + +#else +/* base on SAMA5D3_Xplained Board */ + #define MODALIAS "WILC_SPI" + #define GPIO_NUM 0x44 +#endif + + +void linux_wlan_enable_irq(void); +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_sdio.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_sdio.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#include "wilc_wfi_netdevice.h" + +#include <linux/mmc/sdio_func.h> +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio.h> +#include <linux/mmc/host.h> + + + +#if defined (NM73131_0_BOARD) +#define SDIO_MODALIAS "wilc_sdio" +#else +#define SDIO_MODALIAS "wilc1000_sdio" +#endif + +#if defined (NM73131_0_BOARD) + #define MAX_SPEED 50000000 +#elif defined(CUSTOMER_PLATFORM) +/* TODO : User have to stable bus clock as user's environment. */ + #ifdef MAX_BUS_SPEED + #define MAX_SPEED MAX_BUS_SPEED + #else + #define MAX_SPEED 50000000 + #endif +#else + #define MAX_SPEED (30 * 1000000) /* Max 50M */ +#endif + + +struct sdio_func *local_sdio_func; +extern linux_wlan_t *g_linux_wlan; +extern int wilc_netdev_init(void); +extern int sdio_clear_int(void); +extern void wilc_handle_isr(void); + +static unsigned int sdio_default_speed; + +#define SDIO_VENDOR_ID_WILC 0x0296 +#define SDIO_DEVICE_ID_WILC 0x5347 + +static const struct sdio_device_id wilc_sdio_ids[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) }, +}; + + +static void wilc_sdio_interrupt(struct sdio_func *func) +{ +#ifndef WILC_SDIO_IRQ_GPIO + sdio_release_host(func); + wilc_handle_isr(); + sdio_claim_host(func); +#endif +} + + +int linux_sdio_cmd52(sdio_cmd52_t *cmd) +{ + struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + int ret; + u8 data; + + sdio_claim_host(func); + + func->num = cmd->function; + if (cmd->read_write) { /* write */ + if (cmd->raw) { + sdio_writeb(func, cmd->data, cmd->address, &ret); + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } else { + sdio_writeb(func, cmd->data, cmd->address, &ret); + } + } else { /* read */ + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } + + sdio_release_host(func); + + if (ret < 0) { + PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret); + return 0; + } + return 1; +} + + +int linux_sdio_cmd53(sdio_cmd53_t *cmd) +{ + struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + int size, ret; + + sdio_claim_host(func); + + func->num = cmd->function; + func->cur_blksize = cmd->block_size; + if (cmd->block_mode) + size = cmd->count * cmd->block_size; + else + size = cmd->count; + + if (cmd->read_write) { /* write */ + ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size); + } else { /* read */ + ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size); + } + + sdio_release_host(func); + + + if (ret < 0) { + PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret); + return 0; + } + + return 1; +} + +volatile int probe; /* COMPLEMENT_BOOT */ +static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + PRINT_D(INIT_DBG, "probe function\n"); + +#ifdef COMPLEMENT_BOOT + if (local_sdio_func != NULL) { + local_sdio_func = func; + probe = 1; + PRINT_D(INIT_DBG, "local_sdio_func isn't NULL\n"); + return 0; + } +#endif + PRINT_D(INIT_DBG, "Initializing netdev\n"); + local_sdio_func = func; + if (wilc_netdev_init()) { + PRINT_ER("Couldn't initialize netdev\n"); + return -1; + } + + printk("Driver Initializing success\n"); + return 0; +} + +static void linux_sdio_remove(struct sdio_func *func) +{ + /** + * TODO + **/ + +} + +struct sdio_driver wilc_bus = { + .name = SDIO_MODALIAS, + .id_table = wilc_sdio_ids, + .probe = linux_sdio_probe, + .remove = linux_sdio_remove, +}; + +int enable_sdio_interrupt(void) +{ + int ret = 0; +#ifndef WILC_SDIO_IRQ_GPIO + + sdio_claim_host(local_sdio_func); + ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt); + sdio_release_host(local_sdio_func); + + if (ret < 0) { + PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); + ret = -EIO; + } +#endif + return ret; +} + +void disable_sdio_interrupt(void) +{ + +#ifndef WILC_SDIO_IRQ_GPIO + int ret; + + PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n"); + + sdio_claim_host(local_sdio_func); + ret = sdio_release_irq(local_sdio_func); + if (ret < 0) { + PRINT_ER("can't release sdio_irq, err(%d)\n", ret); + } + sdio_release_host(local_sdio_func); + + PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n"); +#endif +} + +static int linux_sdio_set_speed(int speed) +{ + struct mmc_ios ios; + sdio_claim_host(local_sdio_func); + + memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios)); + local_sdio_func->card->host->ios.clock = speed; + ios.clock = speed; + local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios); + sdio_release_host(local_sdio_func); + PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); + + return 1; +} + +static int linux_sdio_get_speed(void) +{ + return local_sdio_func->card->host->ios.clock; +} + +int linux_sdio_init(void *pv) +{ + + /** + * TODO : + **/ + + + sdio_default_speed = linux_sdio_get_speed(); + return 1; +} + +void linux_sdio_deinit(void *pv) +{ + + /** + * TODO : + **/ + + + sdio_unregister_driver(&wilc_bus); +} + +int linux_sdio_set_max_speed(void) +{ + return linux_sdio_set_speed(MAX_SPEED); +} + +int linux_sdio_set_default_speed(void) +{ + return linux_sdio_set_speed(sdio_default_speed); +} + + + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_sdio.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_sdio.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +extern struct sdio_func *local_sdio_func; +extern struct sdio_driver wilc_bus; + +#include <linux/mmc/sdio_func.h> + +int linux_sdio_init(void *); +void linux_sdio_deinit(void *); +int linux_sdio_cmd52(sdio_cmd52_t *cmd); +int linux_sdio_cmd53(sdio_cmd53_t *cmd); +int enable_sdio_interrupt(void); +void disable_sdio_interrupt(void); +int linux_sdio_set_max_speed(void); +int linux_sdio_set_default_speed(void); + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_spi.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_spi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/cdev.h> +#include <asm/uaccess.h> +#include <linux/device.h> +#include <linux/spi/spi.h> + +#include "linux_wlan_common.h" + +#define USE_SPI_DMA 0 /* johnny add */ + +#ifdef WILC_ASIC_A0 + #if defined(PLAT_PANDA_ES_OMAP4460) + #define MIN_SPEED 12000000 + #define MAX_SPEED 24000000 + #elif defined(PLAT_WMS8304) + #define MIN_SPEED 12000000 + #define MAX_SPEED 24000000 /* 4000000 */ + #elif defined(CUSTOMER_PLATFORM) +/* + TODO : define Clock speed under 48M. + * + * ex) + * #define MIN_SPEED 24000000 + * #define MAX_SPEED 48000000 + */ + #else + #define MIN_SPEED 24000000 + #define MAX_SPEED 48000000 + #endif +#else /* WILC_ASIC_A0 */ +/* Limit clk to 6MHz on FPGA. */ + #define MIN_SPEED 6000000 + #define MAX_SPEED 6000000 +#endif /* WILC_ASIC_A0 */ + +static uint32_t SPEED = MIN_SPEED; + +struct spi_device *wilc_spi_dev; +void linux_spi_deinit(void *vp); + +static int __init wilc_bus_probe(struct spi_device *spi) +{ + + PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias); + PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz); + wilc_spi_dev = spi; + + printk("Driver Initializing success\n"); + return 0; +} + +static int __exit wilc_bus_remove(struct spi_device *spi) +{ + + /* linux_spi_deinit(NULL); */ + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id wilc1000_of_match[] = { + { .compatible = "atmel,wilc_spi", }, + {} +}; +MODULE_DEVICE_TABLE(of, wilc1000_of_match); +#endif + +struct spi_driver wilc_bus __refdata = { + .driver = { + .name = MODALIAS, +#ifdef CONFIG_OF + .of_match_table = wilc1000_of_match, +#endif + }, + .probe = wilc_bus_probe, + .remove = __exit_p(wilc_bus_remove), +}; + + +void linux_spi_deinit(void *vp) +{ + + spi_unregister_driver(&wilc_bus); + + SPEED = MIN_SPEED; + PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED); + +} + + + +int linux_spi_init(void *vp) +{ + int ret = 1; + static int called; + + + if (called == 0) { + called++; + if (&wilc_bus == NULL) { + PRINT_ER("wilc_bus address is NULL\n"); + } + ret = spi_register_driver(&wilc_bus); + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#if defined(PLAT_WMS8304) +#define TXRX_PHASE_SIZE (4096) +#endif + +#if defined (NM73131_0_BOARD) + +int linux_spi_write(uint8_t *b, uint32_t len) +{ + + int ret; + + if (len > 0 && b != NULL) { + struct spi_message msg; + PRINT_D(BUS_DBG, "Request writing %d bytes\n", len); + struct spi_transfer tr = { + .tx_buf = b, + .len = len, + .speed_hz = SPEED, + .delay_usecs = 0, + }; + + spi_message_init(&msg); + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + + return ret; +} + +#elif defined(TXRX_PHASE_SIZE) + +int linux_spi_write(uint8_t *b, uint32_t len) +{ + int ret; + if (len > 0 && b != NULL) { + int i = 0; + int blk = len / TXRX_PHASE_SIZE; + int remainder = len % TXRX_PHASE_SIZE; + + char *r_buffer = (char *) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); + if (!r_buffer) { + PRINT_ER("Failed to allocate memory for r_buffer\n"); + } + + if (blk) { + while (i < blk) { + struct spi_message msg; + struct spi_transfer tr = { + .tx_buf = b + (i * TXRX_PHASE_SIZE), + /* .rx_buf = NULL, */ + .len = TXRX_PHASE_SIZE, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + /* + * char *r_buffer = (char*) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); + * if(! r_buffer){ + * PRINT_ER("Failed to allocate memory for r_buffer\n"); + * } + */ + tr.rx_buf = r_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + /* i += MJ_WRITE_SIZE; */ + i++; + + } + } + if (remainder) { + struct spi_message msg; + struct spi_transfer tr = { + .tx_buf = b + (blk * TXRX_PHASE_SIZE), + /* .rx_buf = NULL, */ + .len = remainder, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + /* + * char *r_buffer = (char*) kzalloc(remainder, GFP_KERNEL); + * if(! r_buffer){ + * PRINT_ER("Failed to allocate memory for r_buffer\n"); + * } + */ + tr.rx_buf = r_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } + if (r_buffer) + kfree(r_buffer); + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; + +} + +#else +int linux_spi_write(uint8_t *b, uint32_t len) +{ + + int ret; + struct spi_message msg; + + if (len > 0 && b != NULL) { + struct spi_transfer tr = { + .tx_buf = b, + /* .rx_buf = r_buffer, */ + .len = len, + .speed_hz = SPEED, + .delay_usecs = 0, + }; + char *r_buffer = (char *) kzalloc(len, GFP_KERNEL); + if (!r_buffer) { + PRINT_ER("Failed to allocate memory for r_buffer\n"); + } + tr.rx_buf = r_buffer; + PRINT_D(BUS_DBG, "Request writing %d bytes\n", len); + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); +/* [[johnny add */ + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; +/* ]] */ + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + + kfree(r_buffer); + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + + return ret; +} + +#endif + +#if defined (NM73131_0_BOARD) + +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .len = rlen, + .speed_hz = SPEED, + .delay_usecs = 0, + + }; + + spi_message_init(&msg); + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#elif defined(TXRX_PHASE_SIZE) + +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + int ret; + + if (rlen > 0) { + int i = 0; + + int blk = rlen / TXRX_PHASE_SIZE; + int remainder = rlen % TXRX_PHASE_SIZE; + + char *t_buffer = (char *) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); + if (!t_buffer) { + PRINT_ER("Failed to allocate memory for t_buffer\n"); + } + + if (blk) { + while (i < blk) { + struct spi_message msg; + struct spi_transfer tr = { + /* .tx_buf = NULL, */ + .rx_buf = rb + (i * TXRX_PHASE_SIZE), + .len = TXRX_PHASE_SIZE, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + i++; + } + } + if (remainder) { + struct spi_message msg; + struct spi_transfer tr = { + /* .tx_buf = NULL, */ + .rx_buf = rb + (blk * TXRX_PHASE_SIZE), + .len = remainder, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + /* + * char *t_buffer = (char*) kzalloc(remainder, GFP_KERNEL); + * if(! t_buffer){ + * PRINT_ER("Failed to allocate memory for t_buffer\n"); + * } + */ + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } + + if (t_buffer) + kfree(t_buffer); + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#else +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + /* .tx_buf = t_buffer, */ + .rx_buf = rb, + .len = rlen, + .speed_hz = SPEED, + .delay_usecs = 0, + + }; + char *t_buffer = (char *) kzalloc(rlen, GFP_KERNEL); + if (!t_buffer) { + PRINT_ER("Failed to allocate memory for t_buffer\n"); + } + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); +/* [[ johnny add */ + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; +/* ]] */ + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + kfree(t_buffer); + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#endif + +int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .tx_buf = wb, + .len = rlen, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + + }; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } else { + PRINT_ER("can't read data with the following length: %d\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +int linux_spi_set_max_speed(void) +{ + SPEED = MAX_SPEED; + + PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED); + return 1; +} Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_spi.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/linux_wlan_spi.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef LINUX_WLAN_SPI_H +#define LINUX_WLAN_SPI_H + +#include <linux/spi/spi.h> +extern struct spi_device *wilc_spi_dev; +extern struct spi_driver wilc_bus; + +int linux_spi_init(void *vp); +void linux_spi_deinit(void *vp); +int linux_spi_write(uint8_t *b, uint32_t len); +int linux_spi_read(uint8_t *rb, uint32_t rlen); +int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen); +int linux_spi_set_max_speed(void); +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/Makefile =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/Makefile @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +obj-$(CONFIG_WILC1000) += wilc1000.o +obj-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += wilc_exported_buf.o + + +ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT +ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO +ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI + +ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ + -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ + -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" + +ccflags-y += -I$(src)/ -DEXPORT_SYMTAB -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \ + -DPLL_WORKAROUND -DCONNECT_DIRECT -DAGING_ALG \ + -DWILC_PARSE_SCAN_IN_HOST -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP \ + -DWILC_PLATFORM=WILC_LINUXKERNEL -Wno-unused-function -DUSE_WIRELESS \ + -DWILC_DEBUGFS +#ccflags-y += -DTCP_ACK_FILTER + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_BOOT + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_INSMOD + +ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC + + +wilc1000-objs := wilc_wfi_netdevice.o wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ + wilc_memory.o wilc_msgqueue.o wilc_semaphore.o wilc_sleep.o wilc_strutils.o \ + wilc_thread.o wilc_time.o wilc_timer.o coreconfigurator.o host_interface.o \ + fifo_buffer.o wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o + +wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o +wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o + +WILC1000_SRC_VERSION = 10.0 +PATCHLEVEL = 2 +WILC1000_FW_VERSION = 0 + +ccflags-y += -D__DRIVER_VERSION__=\"$(WILC1000_SRC_VERSION).$(PATCHLEVEL)\" Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/svnrevision.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/svnrevision.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:2 @ +#ifndef SVNREV_H +#define SVNREV_H +#define SVNREV "249" +#define SVNURL "" +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_debugfs.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_debugfs.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * NewportMedia WiFi chipset driver test tools - wilc-debug + * Copyright (c) 2012 NewportMedia Inc. + * Author: SSW <sswd@wilcsemic.com> + * + * 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. + * + */ + +#if defined(WILC_DEBUGFS) +#include <linux/module.h> +#include <linux/debugfs.h> +#include <linux/poll.h> +#include <linux/sched.h> + +#include "wilc_wlan_if.h" + + +static struct dentry *wilc_dir; + +/* + * -------------------------------------------------------------------------------- + */ + +#define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG) +#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR) +atomic_t REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG); +atomic_t DEBUG_LEVEL = ATOMIC_INIT(ERR); + +/* + * -------------------------------------------------------------------------------- + */ + + +static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) +{ + char buf[128]; + int res = 0; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&DEBUG_LEVEL)); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static ssize_t wilc_debug_level_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) +{ + char buffer[128] = {}; + int flag = 0; + + if (copy_from_user(buffer, buf, count)) { + return -EFAULT; + } + + flag = buffer[0] - '0'; + + if (flag > 0) { + flag = DEBUG | ERR; + } else if (flag < 0) { + flag = 100; + } + + if (flag > DBG_LEVEL_ALL) { + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&DEBUG_LEVEL)); + return -EFAULT; + } + + atomic_set(&DEBUG_LEVEL, (int)flag); + + if (flag == 0) { + printk("Debug-level disabled\n"); + } else { + printk("Debug-level enabled\n"); + } + return count; +} + +static ssize_t wilc_debug_region_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) +{ + char buf[128]; + int res = 0; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(®ION)); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static ssize_t wilc_debug_region_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) +{ + char buffer[128] = {}; + int flag; + + if (copy_from_user(buffer, buf, count)) { + return -EFAULT; + } + + flag = buffer[0] - '0'; + + if (flag > DBG_REGION_ALL) { + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(®ION)); + return -EFAULT; + } + + atomic_set(®ION, (int)flag); + printk("new debug-region is %x\n", atomic_read(®ION)); + + return count; +} + +/* + * -------------------------------------------------------------------------------- + */ + +#define FOPS(_open, _read, _write, _poll) { \ + .owner = THIS_MODULE, \ + .open = (_open), \ + .read = (_read), \ + .write = (_write), \ + .poll = (_poll), \ +} + +struct wilc_debugfs_info_t { + const char *name; + int perm; + unsigned int data; + struct file_operations fops; +}; + +static struct wilc_debugfs_info_t debugfs_info[] = { + { "wilc_debug_level", 0666, (DEBUG | ERR), FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL), }, + { "wilc_debug_region", 0666, (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(NULL, wilc_debug_region_read, wilc_debug_region_write, NULL), }, +}; + +int wilc_debugfs_init(void) +{ + int i; + + struct dentry *debugfs_files; + struct wilc_debugfs_info_t *info; + + wilc_dir = debugfs_create_dir("wilc_wifi", NULL); + if (wilc_dir == ERR_PTR(-ENODEV)) { + /* it's not error. the debugfs is just not being enabled. */ + printk("ERR, kernel has built without debugfs support\n"); + return 0; + } + + if (!wilc_dir) { + printk("ERR, debugfs create dir\n"); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) { + info = &debugfs_info[i]; + debugfs_files = debugfs_create_file(info->name, + info->perm, + wilc_dir, + &info->data, + &info->fops); + + if (!debugfs_files) { + printk("ERR fail to create the debugfs file, %s\n", info->name); + debugfs_remove_recursive(wilc_dir); + return -1; + } + } + return 0; +} + +void wilc_debugfs_remove(void) +{ + debugfs_remove_recursive(wilc_dir); +} + +#endif + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_errorsupport.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_errorsupport.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_ERRORSUPPORT_H__ +#define __WILC_ERRORSUPPORT_H__ + +/*! + * @file wilc_errorsupport.h + * @brief Error reporting and handling support + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Aug 2010 + * @version 1.0 + */ + +#include "linux_wlan_common.h" + +/* Psitive Numbers to indicate sucess with special status */ +#define WILC_ALREADY_EXSIT (+100) /** The requested object already exists */ + +/* Generic success will return 0 */ +#define WILC_SUCCESS 0 /** Generic success */ + +/* Negative numbers to indicate failures */ +#define WILC_FAIL -100 /** Generic Fail */ +#define WILC_BUSY -101 /** Busy with another operation*/ +#define WILC_INVALID_ARGUMENT -102 /** A given argument is invalid*/ +#define WILC_INVALID_STATE -103 /** An API request would violate the Driver state machine (i.e. to start PID while not camped)*/ +#define WILC_BUFFER_OVERFLOW -104 /** In copy operations if the copied data is larger than the allocated buffer*/ +#define WILC_NULL_PTR -105 /** null pointer is passed or used */ +#define WILC_EMPTY -107 +#define WILC_FULL -108 +#define WILC_TIMEOUT -109 +#define WILC_CANCELED -110 /** The required operation have been canceled by the user*/ +#define WILC_INVALID_FILE -112 /** The Loaded file is corruped or having an invalid format */ +#define WILC_NOT_FOUND -113 /** Cant find the file to load */ +#define WILC_NO_MEM -114 +#define WILC_UNSUPPORTED_VERSION -115 +#define WILC_FILE_EOF -116 + + +/* Error type */ +typedef WILC_Sint32 WILC_ErrNo; + +#define WILC_IS_ERR(__status__) (__status__ < WILC_SUCCESS) + +#define WILC_ERRORCHECK(__status__) do { \ + if (WILC_IS_ERR(__status__)) { \ + PRINT_ER("PRINT_ER(%d)\n", __status__); \ + goto ERRORHANDLER; \ + } \ +} while (0) + +#define WILC_ERRORREPORT(__status__, __err__) do { \ + PRINT_ER("PRINT_ER(%d)\n", __err__); \ + __status__ = __err__; \ + goto ERRORHANDLER; \ +} while (0) + +#define WILC_NULLCHECK(__status__, __ptr__) do { \ + if (__ptr__ == WILC_NULL) { \ + WILC_ERRORREPORT(__status__, WILC_NULL_PTR); \ + } \ +} while (0) + +#define WILC_CATCH(__status__) \ +ERRORHANDLER: \ + if (WILC_IS_ERR(__status__)) \ + +#ifdef CONFIG_WILC_ASSERTION_SUPPORT + +/** + * @brief prints a diagnostic message and aborts the program + * @param[in] pcExpression The expression that triggered the assertion + * @param[in] pcFileName The name of the current source file. + * @param[in] u32LineNumber The line number in the current source file. + * @warning DO NOT CALL DIRECTLY. USE EQUIVALENT MACRO FUNCTION INSTEAD. + */ +void WILC_assert_INTERNAL(WILC_Char *pcExpression, WILC_Char *pcFileName, WILC_Uint32 u32LineNumber); + +#define WILC_assert(__expression__) (void)(!!(__expression__) || (WILC_assert_INTERNAL((# __expression__), __WILC_FILE__, __WILC_LINE__), 0)) + +#else +#define WILC_assert(__expression__) ((void)0) +#endif + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_event.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_event.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_EVENT_H__ +#define __WILC_EVENT_H__ + +/*! + * @file wilc_event.h + * @brief Event OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Oct 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_EVENT_FEATURE +#error the feature CONFIG_WILC_EVENT_FEATURE must be supported to include this file +#endif + + +/*! + * @struct tstrWILC_TimerAttrs + * @brief Timer API options + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +typedef struct { + /* a dummy member to avoid compiler errors*/ + WILC_Uint8 dummy; + + #ifdef CONFIG_WILC_EVENT_TIMEOUT + /*!< + * Timeout for use with WILC_EventWait, 0 to return immediately and + * WILC_OS_INFINITY to wait forever. default is WILC_OS_INFINITY + */ + WILC_Uint32 u32TimeOut; + #endif + +} tstrWILC_EventAttrs; + +/*! + * @brief Fills the WILC_TimerAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa WILC_TimerAttrs + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +static void WILC_EventFillDefault(tstrWILC_EventAttrs *pstrAttrs) +{ + #ifdef CONFIG_WILC_EVENT_TIMEOUT + pstrAttrs->u32TimeOut = WILC_OS_INFINITY; + #endif +} + +/*! + * @brief Creates a new Event + * @details the Event is an object that allows a thread to wait until an external + * event occuers, Event objects have 2 states, either TRIGGERED or + * UNTRIGGERED + * @param[out] pHandle handle to the newly created event object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_EventAttrs + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_EventCreate(WILC_EventHandle *pHandle, tstrWILC_EventAttrs *pstrAttrs); + + +/*! + * @brief Destroys a given event + * @details This will destroy a given event freeing any resources used by it + * if there are any thread blocked by the WILC_EventWait call the the + * behaviour is undefined + * @param[in] pHandle handle to the event object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_EventAttrs + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_EventDestroy(WILC_EventHandle *pHandle, + tstrWILC_EventAttrs *pstrAttrs); + +/*! + * @brief Triggers a given event + * @details This function will set the given event into the TRIGGERED state, + * if the event is already in TRIGGERED, this function will have no + * effect + * @param[in] pHandle handle to the event object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_EventAttrs + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_EventTrigger(WILC_EventHandle *pHandle, + tstrWILC_EventAttrs *pstrAttrs); + + +/*! + * @brief waits until a given event is triggered + * @details This function will block the calling thread until the event becomes + * in the TRIGGERED state. the call will retun the event into the + * UNTRIGGERED state upon completion + * if multible threads are waiting on the same event at the same time, + * behaviour is undefined + * @param[in] pHandle handle to the event object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_EventAttrs + * @author syounan + * @date 10 Oct 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_EventWait(WILC_EventHandle *pHandle, + tstrWILC_EventAttrs *pstrAttrs); + + + +#endif \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_exported_buf.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_exported_buf.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/slab.h> + +#define LINUX_RX_SIZE (96 * 1024) +#define LINUX_TX_SIZE (64 * 1024) +#define WILC1000_FW_SIZE (4 * 1024) + +#define DECLARE_WILC_BUFFER(name) \ + void *exported_ ## name = NULL; + +#define MALLOC_WILC_BUFFER(name, size) \ + exported_ ## name = kmalloc(size, GFP_KERNEL); \ + if (!exported_ ## name) { \ + printk("fail to alloc: %s memory\n", exported_ ## name); \ + return -ENOBUFS; \ + } + +#define FREE_WILC_BUFFER(name) \ + kfree(exported_ ## name); + +/* + * Add necessary buffer pointers + */ +DECLARE_WILC_BUFFER(g_tx_buf) +DECLARE_WILC_BUFFER(g_rx_buf) +DECLARE_WILC_BUFFER(g_fw_buf) + +void *get_tx_buffer(void) +{ + return exported_g_tx_buf; +} +EXPORT_SYMBOL(get_tx_buffer); + +void *get_rx_buffer(void) +{ + return exported_g_rx_buf; +} +EXPORT_SYMBOL(get_rx_buffer); + +void *get_fw_buffer(void) +{ + return exported_g_fw_buf; +} +EXPORT_SYMBOL(get_fw_buffer); + +static int __init wilc_module_init(void) +{ + printk("wilc_module_init\n"); + /* + * alloc necessary memory + */ + MALLOC_WILC_BUFFER(g_tx_buf, LINUX_TX_SIZE) + MALLOC_WILC_BUFFER(g_rx_buf, LINUX_RX_SIZE) + MALLOC_WILC_BUFFER(g_fw_buf, WILC1000_FW_SIZE) + + return 0; +} + +static void __exit wilc_module_deinit(void) +{ + printk("wilc_module_deinit\n"); + FREE_WILC_BUFFER(g_tx_buf) + FREE_WILC_BUFFER(g_rx_buf) + FREE_WILC_BUFFER(g_fw_buf) + + return; +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Tony Cho"); +MODULE_DESCRIPTION("WILC1xxx Memory Manager"); +pure_initcall(wilc_module_init); +module_exit(wilc_module_deinit); \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_log.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_log.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_LOG_H__ +#define __WILC_LOG_H__ + +/* Errors will always get printed */ +#define WILC_ERROR(...) do { WILC_PRINTF("(ERR)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) + +/* Wraning only printed if verbosity is 1 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 0) +#define WILC_WARN(...) do { WILC_PRINTF("(WRN)"); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) +#else +#define WILC_WARN(...) (0) +#endif + +/* Info only printed if verbosity is 2 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 1) +#define WILC_INFO(...) do { WILC_PRINTF("(INF)"); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) +#else +#define WILC_INFO(...) (0) +#endif + +/* Debug is only printed if verbosity is 3 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 2) +#define WILC_DBG(...) do { WILC_PRINTF("(DBG)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) + +#else +#define WILC_DBG(...) (0) +#endif + +/* Function In/Out is only printed if verbosity is 4 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 3) +#define WILC_FN_IN do { WILC_PRINTF("(FIN) (%s:%d) \n", __WILC_FUNCTION__, __WILC_LINE__); } while (0) +#define WILC_FN_OUT(ret) do { WILC_PRINTF("(FOUT) (%s:%d) %d.\n", __WILC_FUNCTION__, __WILC_LINE__, (ret)); } while (0) +#else +#define WILC_FN_IN (0) +#define WILC_FN_OUT(ret) (0) +#endif + + +#endif \ No newline at end of file Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_memory.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_memory.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_MEMORY_FEATURE + + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryAlloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + if (u32Size > 0) { + return kmalloc(u32Size, GFP_ATOMIC); + } else { + return WILC_NULL; + } +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryCalloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + return kcalloc(u32Size, 1, GFP_KERNEL); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryRealloc(void *pvOldBlock, WILC_Uint32 u32NewSize, + tstrWILC_MemoryAttrs *strAttrs, WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + if (u32NewSize == 0) { + kfree(pvOldBlock); + return WILC_NULL; + } else if (pvOldBlock == WILC_NULL) { + return kmalloc(u32NewSize, GFP_KERNEL); + } else { + return krealloc(pvOldBlock, u32NewSize, GFP_KERNEL); + } + +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_MemoryFree(void *pvBlock, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + kfree(pvBlock); +} + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_memory.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_memory.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_MEMORY_H__ +#define __WILC_MEMORY_H__ + +/*! + * @file wilc_memory.h + * @brief Memory OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_MEMORY_FEATURE +#error the feature CONFIG_WILC_MEMORY_FEATURE must be supported to include this file +#endif + +/*! + * @struct tstrWILC_MemoryAttrs + * @brief Memory API options + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +typedef struct { + #ifdef CONFIG_WILC_MEMORY_POOLS + /*!< the allocation pool to use for this memory, NULL for system + * allocation. Default is NULL + */ + WILC_MemoryPoolHandle *pAllocationPool; + #endif + + /* a dummy member to avoid compiler errors*/ + WILC_Uint8 dummy; +} tstrWILC_MemoryAttrs; + +/*! + * @brief Fills the tstrWILC_MemoryAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa tstrWILC_MemoryAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +static void WILC_MemoryFillDefault(tstrWILC_MemoryAttrs *pstrAttrs) +{ + #ifdef CONFIG_WILC_MEMORY_POOLS + pstrAttrs->pAllocationPool = WILC_NULL; + #endif +} + +/*! + * @brief Allocates a given size of bytes + * @param[in] u32Size size of memory in bytes to be allocated + * @param[in] strAttrs Optional attributes, NULL for default + * if not NULL, pAllocationPool should point to the pool to use for + * this allocation. if NULL memory will be allocated directly from + * the system + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, NULL if allocation fails + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_MALLOC + * @sa WILC_MALLOC_EX + * @sa WILC_NEW + * @sa WILC_NEW_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryAlloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Allocates a given size of bytes and zero filling it + * @param[in] u32Size size of memory in bytes to be allocated + * @param[in] strAttrs Optional attributes, NULL for default + * if not NULL, pAllocationPool should point to the pool to use for + * this allocation. if NULL memory will be allocated directly from + * the system + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, NULL if allocation fails + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_CALLOC + * @sa WILC_CALLOC_EX + * @sa WILC_NEW_0 + * @sa WILC_NEW_0_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryCalloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Reallocates a given block to a new size + * @param[in] pvOldBlock the old memory block, if NULL then this function + * behaves as a new allocation function + * @param[in] u32NewSize size of the new memory block in bytes, if zero then + * this function behaves as a free function + * @param[in] strAttrs Optional attributes, NULL for default + * if pAllocationPool!=NULL and pvOldBlock==NULL, pAllocationPool + * should point to the pool to use for this allocation. + * if pAllocationPool==NULL and pvOldBlock==NULL memory will be + * allocated directly from the system + * if and pvOldBlock!=NULL, pAllocationPool will not be inspected + * and reallocation is done from the same pool as the original block + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, possibly same as pvOldBlock + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_REALLOC + * @sa WILC_REALLOC_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryRealloc(void *pvOldBlock, WILC_Uint32 u32NewSize, + tstrWILC_MemoryAttrs *strAttrs, WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Frees given block + * @param[in] pvBlock the memory block to be freed + * @param[in] strAttrs Optional attributes, NULL for default + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_FREE + * @sa WILC_FREE_EX + * @sa WILC_FREE_SET_NULL + * @sa WILC_FREE_IF_TRUE + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void WILC_MemoryFree(void *pvBlock, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Creates a new memory pool + * @param[out] pHandle the handle to the new Pool + * @param[in] u32PoolSize The pool size in bytes + * @param[in] strAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa sttrWILC_MemoryAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MemoryNewPool(WILC_MemoryPoolHandle *pHandle, WILC_Uint32 u32PoolSize, + tstrWILC_MemoryAttrs *strAttrs); + +/*! + * @brief Deletes a memory pool, freeing all memory allocated from it as well + * @param[in] pHandle the handle to the deleted Pool + * @param[in] strAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa sttrWILC_MemoryAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MemoryDelPool(WILC_MemoryPoolHandle *pHandle, tstrWILC_MemoryAttrs *strAttrs); + + +#ifdef CONFIG_WILC_MEMORY_DEBUG + +/*! + * @brief standrad malloc wrapper with custom attributes + */ + #define WILC_MALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryAlloc( \ + (__size__), __attrs__, \ + (WILC_Char *)__WILC_FILE__, (WILC_Uint32)__WILC_LINE__)) + +/*! + * @brief standrad calloc wrapper with custom attributes + */ + #define WILC_CALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryCalloc( \ + (__size__), __attrs__, \ + (WILC_Char *)__WILC_FILE__, (WILC_Uint32)__WILC_LINE__)) + +/*! + * @brief standrad realloc wrapper with custom attributes + */ + #define WILC_REALLOC_EX(__ptr__, __new_size__, __attrs__) \ + (WILC_MemoryRealloc( \ + (__ptr__), (__new_size__), __attrs__, \ + (WILC_Char *)__WILC_FILE__, (WILC_Uint32)__WILC_LINE__)) + +/*! + * @brief standrad free wrapper with custom attributes + */ + #define WILC_FREE_EX(__ptr__, __attrs__) \ + (WILC_MemoryFree( \ + (__ptr__), __attrs__, \ + (WILC_Char *)__WILC_FILE__, (WILC_Uint32)__WILC_LINE__)) + +#else + +/*! + * @brief standrad malloc wrapper with custom attributes + */ + #define WILC_MALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryAlloc( \ + (__size__), __attrs__, WILC_NULL, 0)) + +/*! + * @brief standrad calloc wrapper with custom attributes + */ + #define WILC_CALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryCalloc( \ + (__size__), __attrs__, WILC_NULL, 0)) + +/*! + * @brief standrad realloc wrapper with custom attributes + */ + #define WILC_REALLOC_EX(__ptr__, __new_size__, __attrs__) \ + (WILC_MemoryRealloc( \ + (__ptr__), (__new_size__), __attrs__, WILC_NULL, 0)) +/*! + * @brief standrad free wrapper with custom attributes + */ + #define WILC_FREE_EX(__ptr__, __attrs__) \ + (WILC_MemoryFree( \ + (__ptr__), __attrs__, WILC_NULL, 0)) + +#endif + +/*! + * @brief Allocates a block (with custom attributes) of given type and number of + * elements + */ +#define WILC_NEW_EX(__struct_type__, __n_structs__, __attrs__) \ + ((__struct_type__ *)WILC_MALLOC_EX( \ + sizeof(__struct_type__) * (WILC_Uint32)(__n_structs__), __attrs__)) + +/*! + * @brief Allocates a block (with custom attributes) of given type and number of + * elements and Zero-fills it + */ +#define WILC_NEW_0_EX(__struct_type__, __n_structs__, __attrs__) \ + ((__struct_type__ *)WILC_CALLOC_EX( \ + sizeof(__struct_type__) * (WILC_Uint32)(__n_structs__), __attrs__)) + +/*! + * @brief Frees a block (with custom attributes), also setting the original pointer + * to NULL + */ +#define WILC_FREE_SET_NULL_EX(__ptr__, __attrs__) do { \ + if (__ptr__ != WILC_NULL) { \ + WILC_FREE_EX(__ptr__, __attrs__); \ + __ptr__ = WILC_NULL; \ + } \ +} while (0) + +/*! + * @brief Frees a block (with custom attributes) if the pointer expression evaluates + * to true + */ +#define WILC_FREE_IF_TRUE_EX(__ptr__, __attrs__) do { \ + if (__ptr__ != WILC_NULL) { \ + WILC_FREE_EX(__ptr__, __attrs__); \ + } \ +} while (0) + +/*! + * @brief standrad malloc wrapper with default attributes + */ +#define WILC_MALLOC(__size__) \ + WILC_MALLOC_EX(__size__, WILC_NULL) + +/*! + * @brief standrad calloc wrapper with default attributes + */ +#define WILC_CALLOC(__size__) \ + WILC_CALLOC_EX(__size__, WILC_NULL) + +/*! + * @brief standrad realloc wrapper with default attributes + */ +#define WILC_REALLOC(__ptr__, __new_size__) \ + WILC_REALLOC_EX(__ptr__, __new_size__, WILC_NULL) + +/*! + * @brief standrad free wrapper with default attributes + */ +#define WILC_FREE(__ptr__) \ + WILC_FREE_EX(__ptr__, WILC_NULL) + +/*! + * @brief Allocates a block (with default attributes) of given type and number of + * elements + */ +#define WILC_NEW(__struct_type__, __n_structs__) \ + WILC_NEW_EX(__struct_type__, __n_structs__, WILC_NULL) + +/*! + * @brief Allocates a block (with default attributes) of given type and number of + * elements and Zero-fills it + */ +#define WILC_NEW_0(__struct_type__, __n_structs__) \ + WILC_NEW_O_EX(__struct_type__, __n_structs__, WILC_NULL) + +/*! + * @brief Frees a block (with default attributes), also setting the original pointer + * to NULL + */ +#define WILC_FREE_SET_NULL(__ptr__) \ + WILC_FREE_SET_NULL_EX(__ptr__, WILC_NULL) + +/*! + * @brief Frees a block (with default attributes) if the pointer expression evaluates + * to true + */ +#define WILC_FREE_IF_TRUE(__ptr__) \ + WILC_FREE_IF_TRUE_EX(__ptr__, WILC_NULL) + + +#endif + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_msgqueue.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_msgqueue.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" +#include <linux/spinlock.h> +#ifdef CONFIG_WILC_MSG_QUEUE_FEATURE + + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + tstrWILC_SemaphoreAttrs strSemAttrs; + WILC_SemaphoreFillDefault(&strSemAttrs); + strSemAttrs.u32InitCount = 0; + + spin_lock_init(&pHandle->strCriticalSection); + if ((WILC_SemaphoreCreate(&pHandle->hSem, &strSemAttrs) == WILC_SUCCESS)) { + + pHandle->pstrMessageList = NULL; + pHandle->u32ReceiversCount = 0; + pHandle->bExiting = WILC_FALSE; + + return WILC_SUCCESS; + } else { + return WILC_FAIL; + } +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + pHandle->bExiting = WILC_TRUE; + + /* Release any waiting receiver thread. */ + while (pHandle->u32ReceiversCount > 0) { + WILC_SemaphoreRelease(&(pHandle->hSem), WILC_NULL); + pHandle->u32ReceiversCount--; + } + + WILC_SemaphoreDestroy(&pHandle->hSem, WILC_NULL); + + while (pHandle->pstrMessageList != NULL) { + Message *pstrMessge = pHandle->pstrMessageList->pstrNext; + WILC_FREE(pHandle->pstrMessageList); + pHandle->pstrMessageList = pstrMessge; + } + + return WILC_SUCCESS; +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle, + const void *pvSendBuffer, WILC_Uint32 u32SendBufferSize, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + unsigned long flags; + Message *pstrMessage = NULL; + + if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == WILC_TRUE) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + /* construct a new message */ + pstrMessage = WILC_NEW(Message, 1); + WILC_NULLCHECK(s32RetStatus, pstrMessage); + pstrMessage->u32Length = u32SendBufferSize; + pstrMessage->pstrNext = NULL; + pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize); + WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer); + WILC_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize); + + + /* add it to the message queue */ + if (pHandle->pstrMessageList == NULL) { + pHandle->pstrMessageList = pstrMessage; + } else { + Message *pstrTailMsg = pHandle->pstrMessageList; + while (pstrTailMsg->pstrNext != NULL) { + pstrTailMsg = pstrTailMsg->pstrNext; + } + pstrTailMsg->pstrNext = pstrMessage; + } + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + WILC_SemaphoreRelease(&pHandle->hSem, WILC_NULL); + + WILC_CATCH(s32RetStatus) + { + /* error occured, free any allocations */ + if (pstrMessage != NULL) { + if (pstrMessage->pvBuffer != NULL) { + WILC_FREE(pstrMessage->pvBuffer); + } + WILC_FREE(pstrMessage); + } + } + + return s32RetStatus; +} + + + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle, + void *pvRecvBuffer, WILC_Uint32 u32RecvBufferSize, + WILC_Uint32 *pu32ReceivedLength, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + Message *pstrMessage; + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + tstrWILC_SemaphoreAttrs strSemAttrs; + unsigned long flags; + if ((pHandle == NULL) || (u32RecvBufferSize == 0) + || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == WILC_TRUE) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount++; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + WILC_SemaphoreFillDefault(&strSemAttrs); + #ifdef CONFIG_WILC_MSG_QUEUE_TIMEOUT + if (pstrAttrs != WILC_NULL) { + strSemAttrs.u32TimeOut = pstrAttrs->u32Timeout; + } + #endif + s32RetStatus = WILC_SemaphoreAcquire(&(pHandle->hSem), &strSemAttrs); + if (s32RetStatus == WILC_TIMEOUT) { + /* timed out, just exit without consumeing the message */ + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount--; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + } else { + /* other non-timeout scenarios */ + WILC_ERRORCHECK(s32RetStatus); + + if (pHandle->bExiting) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + pstrMessage = pHandle->pstrMessageList; + if (pstrMessage == NULL) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + /* check buffer size */ + if (u32RecvBufferSize < pstrMessage->u32Length) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + WILC_SemaphoreRelease(&pHandle->hSem, WILC_NULL); + WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW); + } + + /* consume the message */ + pHandle->u32ReceiversCount--; + WILC_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length); + *pu32ReceivedLength = pstrMessage->u32Length; + + pHandle->pstrMessageList = pstrMessage->pstrNext; + + WILC_FREE(pstrMessage->pvBuffer); + WILC_FREE(pstrMessage); + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + } + + WILC_CATCH(s32RetStatus) + { + } + + return s32RetStatus; +} + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_msgqueue.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_msgqueue.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_MSG_QUEUE_H__ +#define __WILC_MSG_QUEUE_H__ + +/*! + * @file wilc_msgqueue.h + * @brief Message Queue OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 30 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_MSG_QUEUE_FEATURE +#error the feature CONFIG_WILC_MSG_QUEUE_FEATURE must be supported to include this file +#endif + +/*! + * @struct tstrWILC_MsgQueueAttrs + * @brief Message Queue API options + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +typedef struct { + #ifdef CONFIG_WILC_MSG_QUEUE_IPC_NAME + WILC_Char *pcName; + #endif + + #ifdef CONFIG_WILC_MSG_QUEUE_TIMEOUT + WILC_Uint32 u32Timeout; + #endif + + /* a dummy member to avoid compiler errors*/ + WILC_Uint8 dummy; + +} tstrWILC_MsgQueueAttrs; + +/*! + * @brief Fills the MsgQueueAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa WILC_TimerAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +static void WILC_MsgQueueFillDefault(tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + #ifdef CONFIG_WILC_MSG_QUEUE_IPC_NAME + pstrAttrs->pcName = WILC_NULL; + #endif + + #ifdef CONFIG_WILC_MSG_QUEUE_TIMEOUT + pstrAttrs->u32Timeout = WILC_OS_INFINITY; + #endif +} +/*! + * @brief Creates a new Message queue + * @details Creates a new Message queue, if the feature + * CONFIG_WILC_MSG_QUEUE_IPC_NAME is enabled and pstrAttrs->pcName + * is not Null, then this message queue can be used for IPC with + * any other message queue having the same name in the system + * @param[in,out] pHandle handle to the message queue object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Sends a message + * @details Sends a message, this API will block unil the message is + * actually sent or until it is timedout (as long as the feature + * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout + * is not set to WILC_OS_INFINITY), zero timeout is a valid value + * @param[in] pHandle handle to the message queue object + * @param[in] pvSendBuffer pointer to the data to send + * @param[in] u32SendBufferSize the size of the data to send + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle, + const void *pvSendBuffer, WILC_Uint32 u32SendBufferSize, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Receives a message + * @details Receives a message, this API will block unil a message is + * received or until it is timedout (as long as the feature + * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout + * is not set to WILC_OS_INFINITY), zero timeout is a valid value + * @param[in] pHandle handle to the message queue object + * @param[out] pvRecvBuffer pointer to a buffer to fill with the received message + * @param[in] u32RecvBufferSize the size of the receive buffer + * @param[out] pu32ReceivedLength the length of received data + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle, + void *pvRecvBuffer, WILC_Uint32 u32RecvBufferSize, + WILC_Uint32 *pu32ReceivedLength, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Destroys an existing Message queue + * @param[in] pHandle handle to the message queue object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_osconfig.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_osconfig.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* + * Automatically generated C config: don't edit + * Tue Aug 10 19:52:12 2010 + */ + +/* OSes supported */ +#define WILC_WIN32 0 +#define WILC_NU 1 +#define WILC_MTK 2 +#define WILC_LINUX 3 +#define WILC_LINUXKERNEL 4 +/* the current OS */ +/* #define WILC_PLATFORM WILC_LINUXKERNEL */ + + +/* Logs options */ +#define WILC_LOGS_NOTHING 0 +#define WILC_LOGS_WARN 1 +#define WILC_LOGS_WARN_INFO 2 +#define WILC_LOGS_WARN_INFO_DBG 3 +#define WILC_LOGS_WARN_INFO_DBG_FN 4 +#define WILC_LOGS_ALL 5 + +#define WILC_LOG_VERBOSITY_LEVEL WILC_LOGS_ALL + +/* OS features supported */ + +#define CONFIG_WILC_THREAD_FEATURE 1 +/* #define CONFIG_WILC_THREAD_SUSPEND_CONTROL 1 */ +/* #define CONFIG_WILC_THREAD_STRICT_PRIORITY 1 */ +#define CONFIG_WILC_SEMAPHORE_FEATURE 1 +/* #define CONFIG_WILC_SEMAPHORE_TIMEOUT 1 */ +#define CONFIG_WILC_SLEEP_FEATURE 1 +#define CONFIG_WILC_SLEEP_HI_RES 1 +#define CONFIG_WILC_TIMER_FEATURE 1 +/* #define CONFIG_WILC_TIMER_PERIODIC 1 */ +#define CONFIG_WILC_MEMORY_FEATURE 1 +/* #define CONFIG_WILC_MEMORY_POOLS 1 */ +/* #define CONFIG_WILC_MEMORY_DEBUG 1 */ +/* #define CONFIG_WILC_ASSERTION_SUPPORT 1 */ +#define CONFIG_WILC_STRING_UTILS 1 +#define CONFIG_WILC_MSG_QUEUE_FEATURE +/* #define CONFIG_WILC_MSG_QUEUE_IPC_NAME */ +/* #define CONFIG_WILC_MSG_QUEUE_TIMEOUT */ +/* #define CONFIG_WILC_FILE_OPERATIONS_FEATURE */ +/* #define CONFIG_WILC_FILE_OPERATIONS_STRING_API */ +/* #define CONFIG_WILC_FILE_OPERATIONS_PATH_API */ +#define CONFIG_WILC_TIME_FEATURE +/* #define CONFIG_WILC_EVENT_FEATURE */ +/* #define CONFIG_WILC_EVENT_TIMEOUT */ +/* #define CONFIG_WILC_SOCKET_FEATURE */ +/* #define CONFIG_WILC_MATH_OPERATIONS_FEATURE */ +/* #define CONFIG_WILC_EXTENDED_FILE_OPERATIONS */ +/* #define CONFIG_WILC_EXTENDED_STRING_OPERATIONS */ +/* #define CONFIG_WILC_EXTENDED_TIME_OPERATIONS */ Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_oswrapper.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_oswrapper.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_OSWRAPPER_H__ +#define __WILC_OSWRAPPER_H__ + +/*! + * @file wilc_oswrapper.h + * @brief Top level OS Wrapper, include this file and it will include all + * other files as necessary + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ + +/* OS Wrapper interface version */ +#define WILC_OSW_INTERFACE_VER 2 + +/* Integer Types */ +typedef unsigned char WILC_Uint8; +typedef unsigned short WILC_Uint16; +typedef unsigned int WILC_Uint32; +typedef unsigned long long WILC_Uint64; +typedef signed char WILC_Sint8; +typedef signed short WILC_Sint16; +typedef signed int WILC_Sint32; +typedef signed long long WILC_Sint64; + +/* Floating types */ +typedef float WILC_Float; +typedef double WILC_Double; + +/* Boolean type */ +typedef enum { + WILC_FALSE = 0, + WILC_TRUE = 1 +} WILC_Bool; + +/* Character types */ +typedef char WILC_Char; +typedef WILC_Uint16 WILC_WideChar; + +#define WILC_OS_INFINITY (~((WILC_Uint32)0)) +#define WILC_NULL ((void *)0) + +/* standard min and max macros */ +#define WILC_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define WILC_MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/* Os Configuration File */ +#include "wilc_osconfig.h" + +/* Platform specific include */ +#if WILC_PLATFORM == WILC_WIN32 +#include "wilc_platform.h" +#elif WILC_PLATFORM == WILC_NU +#include "wilc_platform.h" +#elif WILC_PLATFORM == WILC_MTK +#include "wilc_platform.h" +#elif WILC_PLATFORM == WILC_LINUX +#include "wilc_platform.h" +#elif WILC_PLATFORM == WILC_LINUXKERNEL +#include "wilc_platform.h" +#else +#error "OS not supported" +#endif + +/* Logging Functions */ +#include "wilc_log.h" + +/* Error reporting and handling support */ +#include "wilc_errorsupport.h" + +/* Thread support */ +#ifdef CONFIG_WILC_THREAD_FEATURE +#include "wilc_thread.h" +#endif + +/* Semaphore support */ +#ifdef CONFIG_WILC_SEMAPHORE_FEATURE +#include "wilc_semaphore.h" +#endif + +/* Sleep support */ +#ifdef CONFIG_WILC_SLEEP_FEATURE +#include "wilc_sleep.h" +#endif + +/* Timer support */ +#ifdef CONFIG_WILC_TIMER_FEATURE +#include "wilc_timer.h" +#endif + +/* Memory support */ +#ifdef CONFIG_WILC_MEMORY_FEATURE +#include "wilc_memory.h" +#endif + +/* String Utilities */ +#ifdef CONFIG_WILC_STRING_UTILS +#include "wilc_strutils.h" +#endif + +/* Message Queue */ +#ifdef CONFIG_WILC_MSG_QUEUE_FEATURE +#include "wilc_msgqueue.h" +#endif + +/* File operations */ +#ifdef CONFIG_WILC_FILE_OPERATIONS_FEATURE +#include "wilc_fileops.h" +#endif + +/* Time operations */ +#ifdef CONFIG_WILC_TIME_FEATURE +#include "wilc_time.h" +#endif + +/* Event support */ +#ifdef CONFIG_WILC_EVENT_FEATURE +#include "wilc_event.h" +#endif + +/* Socket operations */ +#ifdef CONFIG_WILC_SOCKET_FEATURE +#include "wilc_socket.h" +#endif + +/* Math operations */ +#ifdef CONFIG_WILC_MATH_OPERATIONS_FEATURE +#include "wilc_math.h" +#endif + + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_platform.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_platform.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_platfrom_H__ +#define __WILC_platfrom_H__ + +/*! + * @file wilc_platform.h + * @brief platform specific file for Linux port + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 15 Dec 2010 + * @version 1.0 + */ + + +/****************************************************************** + * Feature support checks + *******************************************************************/ + +/* CONFIG_WILC_THREAD_FEATURE is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_THREAD_SUSPEND_CONTROL +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_THREAD_STRICT_PRIORITY +#error This feature is not supported by this OS +#endif + +/* CONFIG_WILC_SEMAPHORE_FEATURE is implemented */ + +/* remove the following block when implementing its feature + * #ifdef CONFIG_WILC_SEMAPHORE_TIMEOUT + * #error This feature is not supported by this OS + #endif*/ + +/* CONFIG_WILC_SLEEP_FEATURE is implemented */ + +/* remove the following block when implementing its feature */ +/* #ifdef CONFIG_WILC_SLEEP_HI_RES */ +/* #error This feature is not supported by this OS */ +/* #endif */ + +/* CONFIG_WILC_TIMER_FEATURE is implemented */ + +/* CONFIG_WILC_TIMER_PERIODIC is implemented */ + +/* CONFIG_WILC_MEMORY_FEATURE is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_MEMORY_POOLS +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_MEMORY_DEBUG +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_ASSERTION_SUPPORT +#error This feature is not supported by this OS +#endif + +/* CONFIG_WILC_STRING_UTILS is implemented */ + +/* CONFIG_WILC_MSG_QUEUE_FEATURE is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_MSG_QUEUE_IPC_NAME +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +/*#ifdef CONFIG_WILC_MSG_QUEUE_TIMEOUT + * #error This feature is not supported by this OS + #endif*/ + +/* CONFIG_WILC_FILE_OPERATIONS_FEATURE is implemented */ + +/* CONFIG_WILC_FILE_OPERATIONS_STRING_API is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_FILE_OPERATIONS_PATH_API +#error This feature is not supported by this OS +#endif + +/* CONFIG_WILC_TIME_FEATURE is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_TIME_UTC_SINCE_1970 +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_TIME_CALENDER +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_EVENT_FEATURE +#error This feature is not supported by this OS +#endif + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_EVENT_TIMEOUT +#error This feature is not supported by this OS +#endif + +/* CONFIG_WILC_MATH_OPERATIONS_FEATURE is implemented */ + +/* CONFIG_WILC_EXTENDED_FILE_OPERATIONS is implemented */ + +/* CONFIG_WILC_EXTENDED_STRING_OPERATIONS is implemented */ + +/* CONFIG_WILC_EXTENDED_TIME_OPERATIONS is implemented */ + +/* remove the following block when implementing its feature */ +#ifdef CONFIG_WILC_SOCKET_FEATURE +#error This feature is not supported by this OS +#endif + +/****************************************************************** + * OS specific includes + *******************************************************************/ +#define _XOPEN_SOURCE 600 + +#include <linux/kthread.h> +#include <linux/semaphore.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/types.h> +#include <linux/stat.h> +#include <linux/time.h> +#include <linux/version.h> +#include "linux/string.h" +/****************************************************************** + * OS specific types + *******************************************************************/ + +typedef struct task_struct *WILC_ThreadHandle; + +typedef void *WILC_MemoryPoolHandle; +typedef struct semaphore WILC_SemaphoreHandle; + +typedef struct timer_list WILC_TimerHandle; + + + +/* Message Queue type is a structure */ +typedef struct __Message_struct { + void *pvBuffer; + WILC_Uint32 u32Length; + struct __Message_struct *pstrNext; +} Message; + +typedef struct __MessageQueue_struct { + WILC_SemaphoreHandle hSem; + spinlock_t strCriticalSection; + WILC_Bool bExiting; + WILC_Uint32 u32ReceiversCount; + Message *pstrMessageList; +} WILC_MsgQueueHandle; + + + +/*Time represented in 64 bit format*/ +typedef time_t WILC_Time; + + +/******************************************************************* + * others + ********************************************************************/ + +/* Generic printf function */ +#define __WILC_FILE__ __FILE__ +#define __WILC_FUNCTION__ __FUNCTION__ +#define __WILC_LINE__ __LINE__ +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sdio.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sdio.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_sdio.c */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" + + +#ifdef WILC1000_SINGLE_TRANSFER +#define WILC_SDIO_BLOCK_SIZE 256 +#else + #if defined(PLAT_AML8726_M3) /* johnny */ + #define WILC_SDIO_BLOCK_SIZE 512 + #define MAX_SEG_SIZE (1 << 12) /* 4096 */ + #else + #define WILC_SDIO_BLOCK_SIZE 512 + #endif +#endif + +typedef struct { + void *os_context; + wilc_wlan_os_func_t os_func; + uint32_t block_size; + int (*sdio_cmd52)(sdio_cmd52_t *); + int (*sdio_cmd53)(sdio_cmd53_t *); + int (*sdio_set_max_speed)(void); + int (*sdio_set_default_speed)(void); + wilc_debug_func dPrint; + int nint; +#define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */ + int has_thrpt_enh3; +} wilc_sdio_t; + +static wilc_sdio_t g_sdio; + +#ifdef WILC_SDIO_IRQ_GPIO +static int sdio_write_reg(uint32_t addr, uint32_t data); +static int sdio_read_reg(uint32_t addr, uint32_t *data); +#endif +extern unsigned int int_clrd; + +/******************************************** + * + * Function 0 + * + ********************************************/ + +static int sdio_set_func0_csa_address(uint32_t adr) +{ + sdio_cmd52_t cmd; + + /** + * Review: BIG ENDIAN + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10c; + cmd.data = (uint8_t)adr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); + goto _fail_; + } + + cmd.address = 0x10d; + cmd.data = (uint8_t)(adr >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); + goto _fail_; + } + + cmd.address = 0x10e; + cmd.data = (uint8_t)(adr >> 16); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +static int sdio_set_func0_csa_address_byte0(uint32_t adr) +{ + sdio_cmd52_t cmd; + + + /** + * Review: BIG ENDIAN + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10c; + cmd.data = (uint8_t)adr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} +static int sdio_set_func0_block_size(uint32_t block_size) +{ + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10; + cmd.data = (uint8_t)block_size; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); + goto _fail_; + } + + cmd.address = 0x11; + cmd.data = (uint8_t)(block_size >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +/******************************************** + * + * Function 1 + * + ********************************************/ + +static int sdio_set_func1_block_size(uint32_t block_size) +{ + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x110; + cmd.data = (uint8_t)block_size; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); + goto _fail_; + } + cmd.address = 0x111; + cmd.data = (uint8_t)(block_size >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +static int sdio_clear_int(void) +{ +#ifndef WILC_SDIO_IRQ_GPIO + /* uint32_t sts; */ + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x4; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + int_clrd++; + + return cmd.data; +#else + uint32_t reg; + if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + return 0; + } + reg &= ~0x1; + sdio_write_reg(WILC_HOST_RX_CTRL_0, reg); + int_clrd++; + return 1; +#endif + +} + +uint32_t sdio_xfer_cnt(void) +{ + uint32_t cnt = 0; + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1C; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt = cmd.data; + + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1D; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt |= (cmd.data << 8); + + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1E; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt |= (cmd.data << 16); + + return cnt; + + +} + +/******************************************** + * + * Sdio interfaces + * + ********************************************/ +int sdio_check_bs(void) +{ + sdio_cmd52_t cmd; + + /** + * poll until BS is 0 + **/ + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xc; + cmd.data = 0; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n"); + goto _fail_; + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_write_reg(uint32_t addr, uint32_t data) +{ +#ifdef BIG_ENDIAN + data = BYTE_SWAP(data); +#endif + + if ((addr >= 0xf0) && (addr <= 0xff)) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = addr; + cmd.data = data; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + goto _fail_; + } + } else { + sdio_cmd53_t cmd; + + /** + * set the AHB address + **/ + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + + cmd.read_write = 1; + cmd.function = 0; + cmd.address = 0x10f; + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = 4; + cmd.buffer = (uint8_t *)&data; + cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ + + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_write(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint32_t block_size = g_sdio.block_size; + sdio_cmd53_t cmd; + int nblk, nleft; + + cmd.read_write = 1; + if (addr > 0) { + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } + + /** + * func 0 access + **/ + cmd.function = 0; + cmd.address = 0x10f; + } else { +#ifdef WILC1000_SINGLE_TRANSFER + /** + * has to be block aligned... + **/ + nleft = size % block_size; + if (nleft > 0) { + size += block_size; + size &= ~(block_size - 1); + } +#else + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } +#endif + + /** + * func 1 access + **/ + cmd.function = 1; + cmd.address = 0; + } + + nblk = size / block_size; + nleft = size % block_size; + + if (nblk > 0) { + +#if defined(PLAT_AML8726_M3_BACKUP) /* johnny */ + int i; + + for (i = 0; i < nblk; i++) { + cmd.block_mode = 0; /* 1; */ + cmd.increment = 1; + cmd.count = block_size; /* nblk; */ + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += block_size; /* addr += nblk*block_size; */ + + buf += block_size; /* buf += nblk*block_size; */ + } + +#elif defined(PLAT_AML8726_M3) /* johnny */ + + int i; + int rest; + int seg_cnt; + + seg_cnt = (nblk * block_size) / MAX_SEG_SIZE; + rest = (nblk * block_size) & (MAX_SEG_SIZE - 1); + + for (i = 0; i < seg_cnt; i++) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = MAX_SEG_SIZE / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += MAX_SEG_SIZE; + + buf += MAX_SEG_SIZE; + + } + + + if (rest > 0) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = rest / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += rest; + + buf += rest; + + } + +#else + + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = nblk; + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += nblk * block_size; + buf += nblk * block_size; + +#endif /* platform */ + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + + } + + + if (nleft > 0) { + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = nleft; + cmd.buffer = buf; + + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_read_reg(uint32_t addr, uint32_t *data) +{ + if ((addr >= 0xf0) && (addr <= 0xff)) { + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = addr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + goto _fail_; + } + *data = cmd.data; + } else { + sdio_cmd53_t cmd; + + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + + cmd.read_write = 0; + cmd.function = 0; + cmd.address = 0x10f; + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = 4; + cmd.buffer = (uint8_t *)data; + + cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ + + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; + +_fail_: + + return 0; +} + +static int sdio_read(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint32_t block_size = g_sdio.block_size; + sdio_cmd53_t cmd; + int nblk, nleft; + + cmd.read_write = 0; + if (addr > 0) { + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } + + /** + * func 0 access + **/ + cmd.function = 0; + cmd.address = 0x10f; + } else { +#ifdef WILC1000_SINGLE_TRANSFER + /** + * has to be block aligned... + **/ + nleft = size % block_size; + if (nleft > 0) { + size += block_size; + size &= ~(block_size - 1); + } +#else + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } +#endif + + /** + * func 1 access + **/ + cmd.function = 1; + cmd.address = 0; + } + + nblk = size / block_size; + nleft = size % block_size; + + if (nblk > 0) { + +#if defined(PLAT_AML8726_M3_BACKUP) /* johnny */ + + int i; + + for (i = 0; i < nblk; i++) { + cmd.block_mode = 0; /* 1; */ + cmd.increment = 1; + cmd.count = block_size; /* nblk; */ + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += block_size; /* addr += nblk*block_size; */ + buf += block_size; /* buf += nblk*block_size; */ + } + +#elif defined(PLAT_AML8726_M3) /* johnny */ + + int i; + int rest; + int seg_cnt; + + seg_cnt = (nblk * block_size) / MAX_SEG_SIZE; + rest = (nblk * block_size) & (MAX_SEG_SIZE - 1); + + for (i = 0; i < seg_cnt; i++) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = MAX_SEG_SIZE / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; + + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += MAX_SEG_SIZE; + + buf += MAX_SEG_SIZE; + + } + + + if (rest > 0) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = rest / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += rest; + + buf += rest; + + } + +#else + + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = nblk; + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += nblk * block_size; + buf += nblk * block_size; + +#endif /* platform */ + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + + } /* if (nblk > 0) */ + + if (nleft > 0) { + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = nleft; + cmd.buffer = buf; + + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +/******************************************** + * + * Bus interfaces + * + ********************************************/ + +static int sdio_deinit(void *pv) +{ + return 1; +} + +static int sdio_sync(void) +{ + uint32_t reg; + + /** + * Disable power sequencer + **/ + if (!sdio_read_reg(WILC_MISC, ®)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + return 0; + } + + reg &= ~(1 << 8); + if (!sdio_write_reg(WILC_MISC, reg)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + return 0; + } + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t reg; + int ret; + + /** + * interrupt pin mux select + **/ + ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + reg |= (1 << 16); + ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + } +#endif + + return 1; +} + +static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +{ + sdio_cmd52_t cmd; + int loop; + uint32_t chipid; + memset(&g_sdio, 0, sizeof(wilc_sdio_t)); + + g_sdio.dPrint = func; + g_sdio.os_context = inp->os_context.os_private; + memcpy((void *)&g_sdio.os_func, (void *)&inp->os_func, sizeof(wilc_wlan_os_func_t)); + + if (inp->io_func.io_init) { + if (!inp->io_func.io_init(g_sdio.os_context)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); + return 0; + } + } else { + return 0; + } + + g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52; + g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53; + g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed; + g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; + + /** + * function 0 csa enable + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x100; + cmd.data = 0x80; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); + goto _fail_; + } + + /** + * function 0 block size + **/ + if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n"); + goto _fail_; + } + g_sdio.block_size = WILC_SDIO_BLOCK_SIZE; + + /** + * enable func1 IO + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x2; + cmd.data = 0x2; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); + goto _fail_; + } + + /** + * make sure func 1 is up + **/ + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x3; + loop = 3; + do { + cmd.data = 0; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); + goto _fail_; + } + if (cmd.data == 0x2) + break; + } while (loop--); + + if (loop <= 0) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n"); + goto _fail_; + } + + /** + * func 1 is ready, set func 1 block size + **/ + if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n"); + goto _fail_; + } + + /** + * func 1 interrupt enable + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x4; + cmd.data = 0x3; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); + goto _fail_; + } + + /** + * make sure can read back chip id correctly + **/ + if (!sdio_read_reg(0x1000, &chipid)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n"); + goto _fail_; + } + g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid); + if ((chipid & 0xfff) > 0x2a0) { + g_sdio.has_thrpt_enh3 = 1; + } else { + g_sdio.has_thrpt_enh3 = 0; + } + g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3); + + + return 1; + +_fail_: + + return 0; +} + +static void sdio_set_max_speed(void) +{ + g_sdio.sdio_set_max_speed(); +} + +static void sdio_set_default_speed(void) +{ + g_sdio.sdio_set_default_speed(); +} + +static int sdio_read_size(uint32_t *size) +{ + + uint32_t tmp; + sdio_cmd52_t cmd; + + /** + * Read DMA count in words + **/ + { + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf2; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + tmp = cmd.data; + + /* cmd.read_write = 0; */ + /* cmd.function = 0; */ + /* cmd.raw = 0; */ + cmd.address = 0xf3; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + tmp |= (cmd.data << 8); + } + + *size = tmp; + return 1; +} + +static int sdio_read_int(uint32_t *int_status) +{ + + uint32_t tmp; + sdio_cmd52_t cmd; + + sdio_read_size(&tmp); + + /** + * Read IRQ flags + **/ +#ifndef WILC_SDIO_IRQ_GPIO + /* cmd.read_write = 0; */ + cmd.function = 1; + /* cmd.raw = 0; */ + cmd.address = 0x04; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + + if (cmd.data & (1 << 0)) { + tmp |= INT_0; + } + if (cmd.data & (1 << 2)) { + tmp |= INT_1; + } + if (cmd.data & (1 << 3)) { + tmp |= INT_2; + } + if (cmd.data & (1 << 4)) { + tmp |= INT_3; + } + if (cmd.data & (1 << 5)) { + tmp |= INT_4; + } + if (cmd.data & (1 << 6)) { + tmp |= INT_5; + } + { + int i; + for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data); + break; + } + } + } +#else + { + uint32_t irq_flags; + + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf7; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + irq_flags = cmd.data & 0x1f; + tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); + } + +#endif + + *int_status = tmp; + + return 1; +} + +static int sdio_clear_int_ext(uint32_t val) +{ + int ret; + + if (g_sdio.has_thrpt_enh3) { + uint32_t reg; + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t flags; + flags = val & ((1 << MAX_NUN_INT_THRPT_ENH2) - 1); + reg = flags; + } +#else + reg = 0; +#endif + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + reg |= (1 << 5); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + reg |= (1 << 6); + /* enable VMM */ + if ((val & EN_VMM) == EN_VMM) + reg |= (1 << 7); + if (reg) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf8; + cmd.data = reg; + + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + goto _fail_; + } + + } + } else { +#ifdef WILC_SDIO_IRQ_GPIO + { + /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */ + /* Cannot clear multiple interrupts. Must clear each interrupt individually */ + uint32_t flags; + flags = val & ((1 << MAX_NUM_INT) - 1); + if (flags) { + int i; + + ret = 1; + for (i = 0; i < g_sdio.nint; i++) { + if (flags & 1) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf8; + cmd.data = (1 << i); + + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + goto _fail_; + } + + } + if (!ret) + break; + flags >>= 1; + } + if (!ret) { + goto _fail_; + } + for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + if (flags & 1) + g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i); + flags >>= 1; + } + } + } +#endif /* WILC_SDIO_IRQ_GPIO */ + + + { + uint32_t vmm_ctl; + + vmm_ctl = 0; + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + vmm_ctl |= (1 << 0); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + vmm_ctl |= (1 << 1); + /* enable VMM */ + if ((val & EN_VMM) == EN_VMM) + vmm_ctl |= (1 << 2); + + if (vmm_ctl) { + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf6; + cmd.data = vmm_ctl; + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); + goto _fail_; + } + } + } + } + + return 1; +_fail_: + return 0; +} + +static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) +{ + uint32_t reg; + + + if (nint > MAX_NUM_INT) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint); + return 0; + } + if (nint > MAX_NUN_INT_THRPT_ENH2) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n"); + return 0; + } + + + g_sdio.nint = nint; + + /** + * Disable power sequencer + **/ + if (!sdio_read_reg(WILC_MISC, ®)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + return 0; + } + + reg &= ~(1 << 8); + if (!sdio_write_reg(WILC_MISC, reg)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + return 0; + } + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t reg; + int ret, i; + + + /** + * interrupt pin mux select + **/ + ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + for (i = 0; (i < 5) && (nint > 0); i++, nint--) { + reg |= (1 << (27 + i)); + } + ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + if (nint) { + ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + + for (i = 0; (i < 3) && (nint > 0); i++, nint--) { + reg |= (1 << i); + } + + ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + } + } +#endif /* WILC_SDIO_IRQ_GPIO */ + return 1; +} + + +/******************************************** + * + * Global sdio HIF function table + * + ********************************************/ + +wilc_hif_func_t hif_sdio = { + sdio_init, + sdio_deinit, + sdio_read_reg, + sdio_write_reg, + sdio_read, + sdio_write, + sdio_sync, + sdio_clear_int, + sdio_read_int, + sdio_clear_int_ext, + sdio_read_size, + sdio_write, + sdio_read, + sdio_sync_ext, + + sdio_set_max_speed, + sdio_set_default_speed, +}; + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_semaphore.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_semaphore.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" +#ifdef CONFIG_WILC_SEMAPHORE_FEATURE + + +WILC_ErrNo WILC_SemaphoreCreate(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs) +{ + tstrWILC_SemaphoreAttrs strDefaultAttrs; + if (pstrAttrs == WILC_NULL) { + WILC_SemaphoreFillDefault(&strDefaultAttrs); + pstrAttrs = &strDefaultAttrs; + } + + sema_init(pHandle, pstrAttrs->u32InitCount); + return WILC_SUCCESS; + +} + + +WILC_ErrNo WILC_SemaphoreDestroy(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs) +{ + /* nothing to be done ! */ + + return WILC_SUCCESS; + +} + + +WILC_ErrNo WILC_SemaphoreAcquire(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + + #ifndef CONFIG_WILC_SEMAPHORE_TIMEOUT + while (down_interruptible(pHandle)) + ; + + #else + if (pstrAttrs == WILC_NULL) { + down(pHandle); + } else { + + s32RetStatus = down_timeout(pHandle, msecs_to_jiffies(pstrAttrs->u32TimeOut)); + } + #endif + + if (s32RetStatus == 0) { + return WILC_SUCCESS; + } else if (s32RetStatus == -ETIME) { + return WILC_TIMEOUT; + } else { + return WILC_FAIL; + } + + return WILC_SUCCESS; + +} + +WILC_ErrNo WILC_SemaphoreRelease(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs) +{ + + up(pHandle); + return WILC_SUCCESS; + +} + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_semaphore.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_semaphore.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_SEMAPHORE_H__ +#define __WILC_SEMAPHORE_H__ + +/*! + * @file wilc_semaphore.h + * @brief Semaphore OS Wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Aug 2010 + * @version 1.0 + */ + + +#ifndef CONFIG_WILC_SEMAPHORE_FEATURE +#error the feature WILC_OS_FEATURE_SEMAPHORE must be supported to include this file +#endif + +/*! + * @struct WILC_SemaphoreAttrs + * @brief Semaphore API options + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +typedef struct { + /*!< + * Initial count when the semaphore is created. default is 1 + */ + WILC_Uint32 u32InitCount; + + #ifdef CONFIG_WILC_SEMAPHORE_TIMEOUT + /*!< + * Timeout for use with WILC_SemaphoreAcquire, 0 to return immediately and + * WILC_OS_INFINITY to wait forever. default is WILC_OS_INFINITY + */ + WILC_Uint32 u32TimeOut; + #endif + +} tstrWILC_SemaphoreAttrs; + + +/*! + * @brief Fills the WILC_SemaphoreAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa WILC_SemaphoreAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +static void WILC_SemaphoreFillDefault(tstrWILC_SemaphoreAttrs *pstrAttrs) +{ + pstrAttrs->u32InitCount = 1; + #ifdef CONFIG_WILC_SEMAPHORE_TIMEOUT + pstrAttrs->u32TimeOut = WILC_OS_INFINITY; + #endif +} +/*! + * @brief Creates a new Semaphore object + * @param[out] pHandle handle to the newly created semaphore + * @param[in] pstrAttrs Optional attributes, NULL for defaults + * pstrAttrs->u32InitCount controls the initial count + * @return Error code indicating success/failure + * @sa WILC_SemaphoreAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_SemaphoreCreate(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs); + +/*! + * @brief Destroyes an existing Semaphore, releasing any resources + * @param[in] pHandle handle to the semaphore object + * @param[in] pstrAttrs Optional attributes, NULL for defaults + * @return Error code indicating success/failure + * @sa WILC_SemaphoreAttrs + * @todo need to define behaviour if the semaphore delayed while it is pending + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_SemaphoreDestroy(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs); + +/*! + * @brief Acquire the Semaphore object + * @details This function will block until it can Acquire the given + * semaphore, if the feature WILC_OS_FEATURE_SEMAPHORE_TIMEOUT is + * eanbled a timeout value can be passed in pstrAttrs + * @param[in] pHandle handle to the semaphore object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating success/failure + * @sa WILC_SemaphoreAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_SemaphoreAcquire(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs); + +/*! + * @brief Release the Semaphore object + * @param[in] pHandle handle to the semaphore object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_SemaphoreAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_SemaphoreRelease(WILC_SemaphoreHandle *pHandle, + tstrWILC_SemaphoreAttrs *pstrAttrs); + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sleep.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sleep.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_SLEEP_FEATURE + +/* + * @author mdaftedar + * @date 10 Aug 2010 + * @version 1.0 + */ +void WILC_Sleep(WILC_Uint32 u32TimeMilliSec) +{ + if (u32TimeMilliSec <= 4000000) { + WILC_Uint32 u32Temp = u32TimeMilliSec * 1000; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) + usleep_range(u32Temp, u32Temp); +#else + udelay(u32Temp); +#endif + } else { + msleep(u32TimeMilliSec); + } + +} +#endif + +/* #ifdef CONFIG_WILC_SLEEP_HI_RES */ +void WILC_SleepMicrosec(WILC_Uint32 u32TimeMicoSec) +{ + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) + usleep_range(u32TimeMicoSec, u32TimeMicoSec); + #else + udelay(u32TimeMicoSec); + #endif +} +/* #endif */ Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sleep.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_sleep.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_SLEEP_H__ +#define __WILC_SLEEP_H__ + +/*! + * @file wilc_sleep.h + * @brief Sleep OS Wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_SLEEP_FEATURE +#error the feature WILC_OS_FEATURE_SLEEP must be supported to include this file +#endif + +/*! + * @brief forces the current thread to sleep until the given time has elapsed + * @param[in] u32TimeMilliSec Time to sleep in Milli seconds + * @sa WILC_SleepMicrosec + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + * @note This function offers a relatively innacurate and low resolution + * sleep, for accurate high resolution sleep use u32TimeMicoSec + */ +void WILC_Sleep(WILC_Uint32 u32TimeMilliSec); + +#ifdef CONFIG_WILC_SLEEP_HI_RES +/*! + * @brief forces the current thread to sleep until the given time has elapsed + * @param[in] u32TimeMicoSec Time to sleep in Micro seconds + * @sa WILC_Sleep + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + * @note This function offers an acurare high resolution sleep, depends on + * the feature WILC_OS_FEATURE_SLEEP_HI_RES and may not be supported + * on all Operating Systems + */ +void WILC_SleepMicrosec(WILC_Uint32 u32TimeMicoSec); +#endif + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_spi.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_spi.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_spi.c */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" + +extern unsigned int int_clrd; + +/* + * #include <linux/kernel.h> + * #include <linux/string.h> + */ +typedef struct { + void *os_context; + int (*spi_tx)(uint8_t *, uint32_t); + int (*spi_rx)(uint8_t *, uint32_t); + int (*spi_trx)(uint8_t *, uint8_t *, uint32_t); + int (*spi_max_speed)(void); + wilc_debug_func dPrint; + int crc_off; + int nint; + int has_thrpt_enh; +} wilc_spi_t; + +static wilc_spi_t g_spi; + +static int spi_read(uint32_t, uint8_t *, uint32_t); +static int spi_write(uint32_t, uint8_t *, uint32_t); + +/******************************************** + * + * Crc7 + * + ********************************************/ + +static const uint8_t crc7_syndrome_table[256] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 +}; + +static uint8_t crc7_byte(uint8_t crc, uint8_t data) +{ + return crc7_syndrome_table[(crc << 1) ^ data]; +} + +static uint8_t crc7(uint8_t crc, const uint8_t *buffer, uint32_t len) +{ + while (len--) + crc = crc7_byte(crc, *buffer++); + return crc; +} + +/******************************************** + * + * Spi protocol Function + * + ********************************************/ + +#define CMD_DMA_WRITE 0xc1 +#define CMD_DMA_READ 0xc2 +#define CMD_INTERNAL_WRITE 0xc3 +#define CMD_INTERNAL_READ 0xc4 +#define CMD_TERMINATE 0xc5 +#define CMD_REPEAT 0xc6 +#define CMD_DMA_EXT_WRITE 0xc7 +#define CMD_DMA_EXT_READ 0xc8 +#define CMD_SINGLE_WRITE 0xc9 +#define CMD_SINGLE_READ 0xca +#define CMD_RESET 0xcf + +#define N_OK 1 +#define N_FAIL 0 +#define N_RESET -1 +#define N_RETRY -2 + +#define DATA_PKT_SZ_256 256 +#define DATA_PKT_SZ_512 512 +#define DATA_PKT_SZ_1K 1024 +#define DATA_PKT_SZ_4K (4 * 1024) +#define DATA_PKT_SZ_8K (8 * 1024) +#define DATA_PKT_SZ DATA_PKT_SZ_8K + +static int spi_cmd(uint8_t cmd, uint32_t adr, uint32_t data, uint32_t sz, uint8_t clockless) +{ + uint8_t bc[9]; + int len = 5; + int result = N_OK; + + bc[0] = cmd; + switch (cmd) { + case CMD_SINGLE_READ: /* single word (4 bytes) read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + len = 5; + break; + + case CMD_INTERNAL_READ: /* internal register read */ + bc[1] = (uint8_t)(adr >> 8); + if (clockless) + bc[1] |= (1 << 7); + bc[2] = (uint8_t)adr; + bc[3] = 0x00; + len = 5; + break; + + case CMD_TERMINATE: /* termination */ + bc[1] = 0x00; + bc[2] = 0x00; + bc[3] = 0x00; + len = 5; + break; + + case CMD_REPEAT: /* repeat */ + bc[1] = 0x00; + bc[2] = 0x00; + bc[3] = 0x00; + len = 5; + break; + + case CMD_RESET: /* reset */ + bc[1] = 0xff; + bc[2] = 0xff; + bc[3] = 0xff; + len = 5; + break; + + case CMD_DMA_WRITE: /* dma write */ + case CMD_DMA_READ: /* dma read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + bc[4] = (uint8_t)(sz >> 8); + bc[5] = (uint8_t)(sz); + len = 7; + break; + + case CMD_DMA_EXT_WRITE: /* dma extended write */ + case CMD_DMA_EXT_READ: /* dma extended read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + bc[4] = (uint8_t)(sz >> 16); + bc[5] = (uint8_t)(sz >> 8); + bc[6] = (uint8_t)(sz); + len = 8; + break; + + case CMD_INTERNAL_WRITE: /* internal register write */ + bc[1] = (uint8_t)(adr >> 8); + if (clockless) + bc[1] |= (1 << 7); + bc[2] = (uint8_t)(adr); + bc[3] = (uint8_t)(data >> 24); + bc[4] = (uint8_t)(data >> 16); + bc[5] = (uint8_t)(data >> 8); + bc[6] = (uint8_t)(data); + len = 8; + break; + + case CMD_SINGLE_WRITE: /* single word write */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)(adr); + bc[4] = (uint8_t)(data >> 24); + bc[5] = (uint8_t)(data >> 16); + bc[6] = (uint8_t)(data >> 8); + bc[7] = (uint8_t)(data); + len = 9; + break; + + default: + result = N_FAIL; + break; + } + + if (result) { + if (!g_spi.crc_off) + bc[len - 1] = (crc7(0x7f, (const uint8_t *)&bc[0], len - 1)) << 1; + else + len -= 1; + + if (!g_spi.spi_tx(bc, len)) { + PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); + result = N_FAIL; + } + } + + return result; +} + +static int spi_cmd_rsp(uint8_t cmd) +{ + uint8_t rsp; + int result = N_OK; + + /** + * Command/Control response + **/ + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + if (!g_spi.spi_rx(&rsp, 1)) { + result = N_FAIL; + goto _fail_; + } + } + + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n"); + result = N_FAIL; + goto _fail_; + } + + if (rsp != cmd) { + PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp); + result = N_FAIL; + goto _fail_; + } + + /** + * State response + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n"); + result = N_FAIL; + goto _fail_; + } + + if (rsp != 0x00) { + PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp); + result = N_FAIL; + } + +_fail_: + + return result; +} + +static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless) +{ + uint8_t wb[32], rb[32]; + uint8_t wix, rix; + uint32_t len2; + uint8_t rsp; + int len = 0; + int result = N_OK; + + wb[0] = cmd; + switch (cmd) { + case CMD_SINGLE_READ: /* single word (4 bytes) read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + len = 5; + break; + + case CMD_INTERNAL_READ: /* internal register read */ + wb[1] = (uint8_t)(adr >> 8); + if (clockless == 1) + wb[1] |= (1 << 7); + wb[2] = (uint8_t)adr; + wb[3] = 0x00; + len = 5; + break; + + case CMD_TERMINATE: /* termination */ + wb[1] = 0x00; + wb[2] = 0x00; + wb[3] = 0x00; + len = 5; + break; + + case CMD_REPEAT: /* repeat */ + wb[1] = 0x00; + wb[2] = 0x00; + wb[3] = 0x00; + len = 5; + break; + + case CMD_RESET: /* reset */ + wb[1] = 0xff; + wb[2] = 0xff; + wb[3] = 0xff; + len = 5; + break; + + case CMD_DMA_WRITE: /* dma write */ + case CMD_DMA_READ: /* dma read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + wb[4] = (uint8_t)(sz >> 8); + wb[5] = (uint8_t)(sz); + len = 7; + break; + + case CMD_DMA_EXT_WRITE: /* dma extended write */ + case CMD_DMA_EXT_READ: /* dma extended read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + wb[4] = (uint8_t)(sz >> 16); + wb[5] = (uint8_t)(sz >> 8); + wb[6] = (uint8_t)(sz); + len = 8; + break; + + case CMD_INTERNAL_WRITE: /* internal register write */ + wb[1] = (uint8_t)(adr >> 8); + if (clockless == 1) + wb[1] |= (1 << 7); + wb[2] = (uint8_t)(adr); + wb[3] = b[3]; + wb[4] = b[2]; + wb[5] = b[1]; + wb[6] = b[0]; + len = 8; + break; + + case CMD_SINGLE_WRITE: /* single word write */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)(adr); + wb[4] = b[3]; + wb[5] = b[2]; + wb[6] = b[1]; + wb[7] = b[0]; + len = 9; + break; + + default: + result = N_FAIL; + break; + } + + if (result != N_OK) { + return result; + } + + if (!g_spi.crc_off) { + wb[len - 1] = (crc7(0x7f, (const uint8_t *)&wb[0], len - 1)) << 1; + } else { + len -= 1; + } + +#define NUM_SKIP_BYTES (1) +#define NUM_RSP_BYTES (2) +#define NUM_DATA_HDR_BYTES (1) +#define NUM_DATA_BYTES (4) +#define NUM_CRC_BYTES (2) +#define NUM_DUMMY_BYTES (3) + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES); + } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + if (!g_spi.crc_off) { + len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + + NUM_CRC_BYTES + NUM_DUMMY_BYTES); + } else { + len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + + NUM_DUMMY_BYTES); + } + } else { + len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES); + } +#undef NUM_DUMMY_BYTES + + if (len2 > (sizeof(wb) / sizeof(wb[0]))) { + PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%d)\n", + len2, (sizeof(wb) / sizeof(wb[0]))); + result = N_FAIL; + return result; + } + /* zero spi write buffers. */ + for (wix = len; wix < len2; wix++) { + wb[wix] = 0; + } + rix = len; + + if (!g_spi.spi_trx(wb, rb, len2)) { + PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); + result = N_FAIL; + return result; + } + +#if 0 + { + int jj; + PRINT_D(BUS_DBG, "--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2); + for (jj = 0; jj < sizeof(wb) / sizeof(wb[0]); jj++) { + + if (jj >= len2) + break; + if (((jj + 1) % 16) != 0) { + if ((jj % 16) == 0) { + PRINT_D(BUS_DBG, "wb[%02x]: %02x ", jj, wb[jj]); + } else { + PRINT_D(BUS_DBG, "%02x ", wb[jj]); + } + } else { + PRINT_D(BUS_DBG, "%02x\n", wb[jj]); + } + } + + for (jj = 0; jj < sizeof(rb) / sizeof(rb[0]); jj++) { + + if (jj >= len2) + break; + if (((jj + 1) % 16) != 0) { + if ((jj % 16) == 0) { + PRINT_D(BUS_DBG, "rb[%02x]: %02x ", jj, rb[jj]); + } else { + PRINT_D(BUS_DBG, "%02x ", rb[jj]); + } + } else { + PRINT_D(BUS_DBG, "%02x\n", rb[jj]); + } + } + } +#endif + + /** + * Command/Control response + **/ + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + rix++; /* skip 1 byte */ + } + + /* do { */ + rsp = rb[rix++]; + /* if(rsp == cmd) break; */ + /* } while(&rptr[1] <= &rb[len2]); */ + + if (rsp != cmd) { + PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)" + ", resp (%02x)\n", cmd, rsp); + result = N_FAIL; + return result; + } + + /** + * State response + **/ + rsp = rb[rix++]; + if (rsp != 0x00) { + PRINT_ER("[wilc spi]: Failed cmd state response " + "state (%02x)\n", rsp); + result = N_FAIL; + return result; + } + + if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ) + || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) { + int retry; + /* uint16_t crc1, crc2; */ + uint8_t crc[2]; + /** + * Data Respnose header + **/ + retry = 100; + do { + /* ensure there is room in buffer later to read data and crc */ + if (rix < len2) { + rsp = rb[rix++]; + } else { + retry = 0; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (retry <= 0) { + PRINT_ER("[wilc spi]: Error, data read " + "response (%02x)\n", rsp); + result = N_RESET; + return result; + } + + if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + /** + * Read bytes + **/ + if ((rix + 3) < len2) { + b[0] = rb[rix++]; + b[1] = rb[rix++]; + b[2] = rb[rix++]; + b[3] = rb[rix++]; + } else { + PRINT_ER("[wilc spi]: buffer overrun when reading data.\n"); + result = N_FAIL; + return result; + } + + if (!g_spi.crc_off) { + /** + * Read Crc + **/ + if ((rix + 1) < len2) { + crc[0] = rb[rix++]; + crc[1] = rb[rix++]; + } else { + PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n"); + result = N_FAIL; + return result; + } + } + } else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) { + int ix; + + /* some data may be read in response to dummy bytes. */ + for (ix = 0; (rix < len2) && (ix < sz); ) { + b[ix++] = rb[rix++]; + } +#if 0 + if (ix) + PRINT_D(BUS_DBG, "ttt %d %d\n", sz, ix); +#endif + sz -= ix; + + if (sz > 0) { + int nbytes; + + if (sz <= (DATA_PKT_SZ - ix)) { + nbytes = sz; + } else { + nbytes = DATA_PKT_SZ - ix; + } + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + goto _error_; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + goto _error_; + } + } + + + ix += nbytes; + sz -= nbytes; + } + + /* if any data in left unread, then read the rest using normal DMA code.*/ + while (sz > 0) { + int nbytes; + +#if 0 + PRINT_INFO(BUS_DBG, "rrr %d %d\n", sz, ix); +#endif + if (sz <= DATA_PKT_SZ) { + nbytes = sz; + } else { + nbytes = DATA_PKT_SZ; + } + + /** + * read data response only on the next DMA cycles not + * the first DMA since data response header is already + * handled above for the first DMA. + **/ + /** + * Data Respnose header + **/ + retry = 10; + do { + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); + result = N_FAIL; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (result == N_FAIL) + break; + + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + break; + } + } + + ix += nbytes; + sz -= nbytes; + } + } + } +_error_: + return result; +} + +static int spi_data_read(uint8_t *b, uint32_t sz) +{ + int retry, ix, nbytes; + int result = N_OK; + uint8_t crc[2]; + uint8_t rsp; + + /** + * Data + **/ + ix = 0; + do { + if (sz <= DATA_PKT_SZ) + nbytes = sz; + else + nbytes = DATA_PKT_SZ; + + /** + * Data Respnose header + **/ + retry = 10; + do { + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); + result = N_FAIL; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (result == N_FAIL) + break; + + if (retry <= 0) { + PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp); + result = N_FAIL; + break; + } + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + break; + } + } + + ix += nbytes; + sz -= nbytes; + + } while (sz); + + return result; +} + +static int spi_data_write(uint8_t *b, uint32_t sz) +{ + int ix, nbytes; + int result = 1; + uint8_t cmd, order, crc[2] = {0}; + /* uint8_t rsp; */ + + /** + * Data + **/ + ix = 0; + do { + if (sz <= DATA_PKT_SZ) + nbytes = sz; + else + nbytes = DATA_PKT_SZ; + + /** + * Write command + **/ + cmd = 0xf0; + if (ix == 0) { + if (sz <= DATA_PKT_SZ) + + order = 0x3; + else + order = 0x1; + } else { + if (sz <= DATA_PKT_SZ) + order = 0x3; + else + order = 0x2; + } + cmd |= order; + if (!g_spi.spi_tx(&cmd, 1)) { + PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Write data + **/ + if (!g_spi.spi_tx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Write Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_tx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); + result = N_FAIL; + break; + } + } + + /** + * No need to wait for response + **/ +#if 0 + /** + * Respnose + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data block write, response read, bus error...\n"); + result = N_FAIL; + break; + } + + if (((rsp >> 4) & 0xf) != 0xc) { + result = N_FAIL; + PRINT_ER("[wilc spi]: Failed data block write response...(%02x)\n", rsp); + break; + } + + /** + * State + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data block write, read state, bus error...\n"); + result = N_FAIL; + break; + } +#endif + + ix += nbytes; + sz -= nbytes; + } while (sz); + + + return result; +} + +/******************************************** + * + * Spi Internal Read/Write Function + * + ********************************************/ + +static int spi_internal_write(uint32_t adr, uint32_t dat) +{ + int result; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(CMD_INTERNAL_WRITE, adr, dat, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); + return 0; + } + + result = spi_cmd_rsp(CMD_INTERNAL_WRITE, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd response...\n"); + } +#else + +#ifdef BIG_ENDIAN + dat = BYTE_SWAP(dat); +#endif + result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (uint8_t *)&dat, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); + } + +#endif + return result; +} + +static int spi_internal_read(uint32_t adr, uint32_t *data) +{ + int result; + +#if defined USE_OLD_SPI_SW + result = spi_cmd(CMD_INTERNAL_READ, adr, 0, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); + return 0; + } + + result = spi_cmd_rsp(CMD_INTERNAL_READ, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd response...\n"); + return 0; + } + + /** + * Data + **/ + result = spi_data_read((uint8_t *)data, 4); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read data...\n"); + return 0; + } +#else + result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (uint8_t *)data, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); + return 0; + } +#endif + + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; +} + +/******************************************** + * + * Spi interfaces + * + ********************************************/ + +static int spi_write_reg(uint32_t addr, uint32_t data) +{ + int result = N_OK; + uint8_t cmd = CMD_SINGLE_WRITE; + uint8_t clockless = 0; + + +#if defined USE_OLD_SPI_SW + { + result = spi_cmd(cmd, addr, data, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, write reg (%08x)...\n", addr); + return 0; + } + + return 1; + } +#else +#ifdef BIG_ENDIAN + data = BYTE_SWAP(data); +#endif + if (addr < 0x30) { + /* Clockless register*/ + cmd = CMD_INTERNAL_WRITE; + clockless = 1; + } + + result = spi_cmd_complete(cmd, addr, (uint8_t *)&data, 4, clockless); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); + } + + return result; +#endif + +} + +static int spi_write(uint32_t addr, uint8_t *buf, uint32_t size) +{ + int result; + uint8_t cmd = CMD_DMA_EXT_WRITE; + + /** + * has to be greated than 4 + **/ + if (size <= 4) + return 0; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(cmd, addr, 0, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi ]: Failed cmd response, write block (%08x)...\n", addr); + return 0; + } +#else + result = spi_cmd_complete(cmd, addr, NULL, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); + return 0; + } +#endif + + /** + * Data + **/ + result = spi_data_write(buf, size); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed block data write...\n"); + } + + return 1; +} + +static int spi_read_reg(uint32_t addr, uint32_t *data) +{ + int result = N_OK; + uint8_t cmd = CMD_SINGLE_READ; + uint8_t clockless = 0; + +#if defined USE_OLD_SPI_SW + result = spi_cmd(cmd, addr, 0, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); + return 0; + } + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, read reg (%08x)...\n", addr); + return 0; + } + + result = spi_data_read((uint8_t *)data, 4); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed data read...\n"); + return 0; + } +#else + if (addr < 0x30) { + /* PRINT_ER("***** read addr %d\n\n", addr); */ + /* Clockless register*/ + cmd = CMD_INTERNAL_READ; + clockless = 1; + } + + result = spi_cmd_complete(cmd, addr, (uint8_t *)data, 4, clockless); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); + return 0; + } +#endif + + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; +} + +static int spi_read(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint8_t cmd = CMD_DMA_EXT_READ; + int result; + + if (size <= 4) + return 0; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(cmd, addr, 0, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, read block (%08x)...\n", addr); + return 0; + } + + /** + * Data + **/ + result = spi_data_read(buf, size); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed block data read...\n"); + return 0; + } +#else + result = spi_cmd_complete(cmd, addr, buf, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); + return 0; + } +#endif + + + return 1; +} + +/******************************************** + * + * Bus interfaces + * + ********************************************/ + +static int spi_clear_int(void) +{ + uint32_t reg; + if (!spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + return 0; + } + reg &= ~0x1; + spi_write_reg(WILC_HOST_RX_CTRL_0, reg); + int_clrd++; + return 1; +} + +static int spi_deinit(void *pv) +{ + /** + * TODO: + **/ + return 1; +} + +static int spi_sync(void) +{ + uint32_t reg; + int ret; + + /** + * interrupt pin mux select + **/ + ret = spi_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = spi_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = spi_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + reg |= (1 << 16); + ret = spi_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + return 1; +} + +static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +{ + uint32_t reg; + uint32_t chipid; + + static int isinit; + + if (isinit) { + + if (!spi_read_reg(0x1000, &chipid)) { + PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + return 0; + } + return 1; + } + + memset(&g_spi, 0, sizeof(wilc_spi_t)); + + g_spi.dPrint = func; + g_spi.os_context = inp->os_context.os_private; + if (inp->io_func.io_init) { + if (!inp->io_func.io_init(g_spi.os_context)) { + PRINT_ER("[wilc spi]: Failed io init bus...\n"); + return 0; + } + } else { + return 0; + } + g_spi.spi_tx = inp->io_func.u.spi.spi_tx; + g_spi.spi_rx = inp->io_func.u.spi.spi_rx; + g_spi.spi_trx = inp->io_func.u.spi.spi_trx; + g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; + + /** + * configure protocol + **/ + g_spi.crc_off = 0; + + /* TODO: We can remove the CRC trials if there is a definite way to reset */ + /* the SPI to it's initial value. */ + if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + /* Read failed. Try with CRC off. This might happen when module + * is removed but chip isn't reset*/ + g_spi.crc_off = 1; + PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n", __LINE__); + if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + /* Reaad failed with both CRC on and off, something went bad */ + PRINT_ER("[wilc spi]: Failed internal read protocol...\n", __LINE__); + return 0; + } + } + if (g_spi.crc_off == 0) { + reg &= ~0xc; /* disable crc checking */ + reg &= ~0x70; + reg |= (0x5 << 4); + if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) { + PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__); + return 0; + } + g_spi.crc_off = 1; + } + + + /** + * make sure can read back chip id correctly + **/ + if (!spi_read_reg(0x1000, &chipid)) { + PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + return 0; + } + /* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */ + + g_spi.has_thrpt_enh = 1; + + isinit = 1; + + return 1; +} + +static void spi_max_bus_speed(void) +{ + g_spi.spi_max_speed(); +} + +static void spi_default_bus_speed(void) +{ +} + +static int spi_read_size(uint32_t *size) +{ + int ret; + if (g_spi.has_thrpt_enh) { + ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size); + *size = *size & IRQ_DMA_WD_CNT_MASK; + } else { + uint32_t tmp; + uint32_t byte_cnt; + + ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + goto _fail_; + } + tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; + *size = tmp; + } + + + +_fail_: + return ret; +} + + + +static int spi_read_int(uint32_t *int_status) +{ + int ret; + if (g_spi.has_thrpt_enh) { + ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status); + } else { + uint32_t tmp; + uint32_t byte_cnt; + + ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + goto _fail_; + } + tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; + + { + int happended, j; + + j = 0; + do { + uint32_t irq_flags; + + happended = 0; + + spi_read_reg(0x1a90, &irq_flags); + tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET); + + if (g_spi.nint > 5) { + spi_read_reg(0x1a94, &irq_flags); + tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5)); + } + + { + uint32_t unkmown_mask; + + unkmown_mask = ~((1ul << g_spi.nint) - 1); + + if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) { + PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask); + happended = 1; + } + } + j++; + } while (happended); + } + + *int_status = tmp; + + } + +_fail_: + return ret; +} + +static int spi_clear_int_ext(uint32_t val) +{ + int ret; + + if (g_spi.has_thrpt_enh) { + ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val); + } else { + uint32_t flags; + flags = val & ((1 << MAX_NUM_INT) - 1); + if (flags) { + int i; + + ret = 1; + for (i = 0; i < g_spi.nint; i++) { + /* No matter what you write 1 or 0, it will clear interrupt. */ + if (flags & 1) + ret = spi_write_reg(0x10c8 + i * 4, 1); + if (!ret) + break; + flags >>= 1; + } + if (!ret) { + PRINT_ER("[wilc spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4); + goto _fail_; + } + for (i = g_spi.nint; i < MAX_NUM_INT; i++) { + if (flags & 1) + PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i); + flags >>= 1; + } + } + + { + uint32_t tbl_ctl; + + tbl_ctl = 0; + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + tbl_ctl |= (1 << 0); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + tbl_ctl |= (1 << 1); + + ret = spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl); + if (!ret) { + PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n"); + goto _fail_; + } + + if ((val & EN_VMM) == EN_VMM) { + /** + * enable vmm transfer. + **/ + ret = spi_write_reg(WILC_VMM_CORE_CTL, 1); + if (!ret) { + PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n"); + goto _fail_; + } + } + } + } +_fail_: + return ret; +} + +static int spi_sync_ext(int nint /* how mant interrupts to enable. */) +{ + uint32_t reg; + int ret, i; + + if (nint > MAX_NUM_INT) { + PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint); + return 0; + } + + g_spi.nint = nint; + + /** + * interrupt pin mux select + **/ + ret = spi_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = spi_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = spi_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + for (i = 0; (i < 5) && (nint > 0); i++, nint--) { + reg |= (1 << (27 + i)); + } + ret = spi_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + if (nint) { + ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + + for (i = 0; (i < 3) && (nint > 0); i++, nint--) { + reg |= (1 << i); + } + + ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + } + + return 1; +} +/******************************************** + * + * Global spi HIF function table + * + ********************************************/ +wilc_hif_func_t hif_spi = { + spi_init, + spi_deinit, + spi_read_reg, + spi_write_reg, + spi_read, + spi_write, + spi_sync, + spi_clear_int, + spi_read_int, + spi_clear_int_ext, + spi_read_size, + spi_write, + spi_read, + spi_sync_ext, + spi_max_bus_speed, + spi_default_bus_speed, +}; + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_strutils.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_strutils.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#define _CRT_SECURE_NO_DEPRECATE + +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_STRING_UTILS + + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_memcmp(const void *pvArg1, const void *pvArg2, WILC_Uint32 u32Count) +{ + return memcmp(pvArg1, pvArg2, u32Count); +} + + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_memcpy_INTERNAL(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count) +{ + memcpy(pvTarget, pvSource, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_memset(void *pvTarget, WILC_Uint8 u8SetValue, WILC_Uint32 u32Count) +{ + return memset(pvTarget, u8SetValue, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncat(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count) +{ + return strncat(pcTarget, pcSource, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncpy(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count) +{ + return strncpy(pcTarget, pcSource, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strcmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2) +{ + WILC_Sint32 s32Result; + + if (pcStr1 == WILC_NULL && pcStr2 == WILC_NULL) { + s32Result = 0; + } else if (pcStr1 == WILC_NULL) { + s32Result = -1; + } else if (pcStr2 == WILC_NULL) { + s32Result = 1; + } else { + s32Result = strcmp(pcStr1, pcStr2); + if (s32Result < 0) { + s32Result = -1; + } else if (s32Result > 0) { + s32Result = 1; + } + } + + return s32Result; +} + +WILC_Sint32 WILC_strncmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count) +{ + WILC_Sint32 s32Result; + + if (pcStr1 == WILC_NULL && pcStr2 == WILC_NULL) { + s32Result = 0; + } else if (pcStr1 == WILC_NULL) { + s32Result = -1; + } else if (pcStr2 == WILC_NULL) { + s32Result = 1; + } else { + s32Result = strncmp(pcStr1, pcStr2, u32Count); + if (s32Result < 0) { + s32Result = -1; + } else if (s32Result > 0) { + s32Result = 1; + } + } + + return s32Result; +} + +/* + * @author syounan + * @date 1 Nov 2010 + * @version 2.0 + */ +WILC_Sint32 WILC_strcmp_IgnoreCase(const WILC_Char *pcStr1, const WILC_Char *pcStr2) +{ + WILC_Sint32 s32Result; + + if (pcStr1 == WILC_NULL && pcStr2 == WILC_NULL) { + s32Result = 0; + } else if (pcStr1 == WILC_NULL) { + s32Result = -1; + } else if (pcStr2 == WILC_NULL) { + s32Result = 1; + } else { + WILC_Char cTestedChar1, cTestedChar2; + do { + cTestedChar1 = *pcStr1; + if ((*pcStr1 >= 'a') && (*pcStr1 <= 'z')) { + /* turn a lower case character to an upper case one */ + cTestedChar1 -= 32; + } + + cTestedChar2 = *pcStr2; + if ((*pcStr2 >= 'a') && (*pcStr2 <= 'z')) { + /* turn a lower case character to an upper case one */ + cTestedChar2 -= 32; + } + + pcStr1++; + pcStr2++; + + } while ((cTestedChar1 == cTestedChar2) + && (cTestedChar1 != 0) + && (cTestedChar2 != 0)); + + if (cTestedChar1 > cTestedChar2) { + s32Result = 1; + } else if (cTestedChar1 < cTestedChar2) { + s32Result = -1; + } else { + s32Result = 0; + } + } + + return s32Result; +} + +/*! + * @author aabozaeid + * @date 8 Dec 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strncmp_IgnoreCase(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count) +{ + WILC_Sint32 s32Result; + + if (pcStr1 == WILC_NULL && pcStr2 == WILC_NULL) { + s32Result = 0; + } else if (pcStr1 == WILC_NULL) { + s32Result = -1; + } else if (pcStr2 == WILC_NULL) { + s32Result = 1; + } else { + WILC_Char cTestedChar1, cTestedChar2; + do { + cTestedChar1 = *pcStr1; + if ((*pcStr1 >= 'a') && (*pcStr1 <= 'z')) { + /* turn a lower case character to an upper case one */ + cTestedChar1 -= 32; + } + + cTestedChar2 = *pcStr2; + if ((*pcStr2 >= 'a') && (*pcStr2 <= 'z')) { + /* turn a lower case character to an upper case one */ + cTestedChar2 -= 32; + } + + pcStr1++; + pcStr2++; + u32Count--; + + } while ((u32Count > 0) + && (cTestedChar1 == cTestedChar2) + && (cTestedChar1 != 0) + && (cTestedChar2 != 0)); + + if (cTestedChar1 > cTestedChar2) { + s32Result = 1; + } else if (cTestedChar1 < cTestedChar2) { + s32Result = -1; + } else { + s32Result = 0; + } + } + + return s32Result; + +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strlen(const WILC_Char *pcStr) +{ + return (WILC_Uint32)strlen(pcStr); +} + +/*! + * @author bfahmy + * @date 28 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strtoint(const WILC_Char *pcStr) +{ + return (WILC_Sint32)(simple_strtol(pcStr, NULL, 10)); +} + +/* + * @author syounan + * @date 1 Nov 2010 + * @version 2.0 + */ +WILC_ErrNo WILC_snprintf(WILC_Char *pcTarget, WILC_Uint32 u32Size, + const WILC_Char *pcFormat, ...) +{ + va_list argptr; + va_start(argptr, pcFormat); + if (vsnprintf(pcTarget, u32Size, pcFormat, argptr) < 0) { + /* if turncation happens windows does not properly terminate strings */ + pcTarget[u32Size - 1] = 0; + } + va_end(argptr); + + /* I find no sane way of detecting errors in windows, so let it all succeed ! */ + return WILC_SUCCESS; +} + +#ifdef CONFIG_WILC_EXTENDED_STRING_OPERATIONS + +/** + * @brief + * @details Searches for the first occurrence of the character c in the first n bytes + * of the string pointed to by the argument str. + * Returns a pointer pointing to the first matching character, + * or null if no match was found. + * @param[in] + * @return + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_memchr(const void *str, WILC_Char c, WILC_Sint32 n) +{ + return (WILC_Char *) memchr(str, c, (size_t)n); +} + +/** + * @brief + * @details Searches for the first occurrence of the character c (an unsigned char) + * in the string pointed to by the argument str. + * The terminating null character is considered to be part of the string. + * Returns a pointer pointing to the first matching character, + * or null if no match was found. + * @param[in] + * @return + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strchr(const WILC_Char *str, WILC_Char c) +{ + return strchr(str, c); +} + +/** + * @brief + * @details Appends the string pointed to by str2 to the end of the string pointed to by str1. + * The terminating null character of str1 is overwritten. + * Copying stops once the terminating null character of str2 is copied. If overlapping occurs, the result is undefined. + * The argument str1 is returned. + * @param[in] WILC_Char* str1, + * @param[in] WILC_Char* str2, + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strcat(WILC_Char *str1, const WILC_Char *str2) +{ + return strcat(str1, str2); +} + +/** + * @brief + * @details Copy pcSource to pcTarget + * @param[in] WILC_Char* pcTarget + * @param[in] const WILC_Char* pcSource + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strcpy(WILC_Char *pcTarget, const WILC_Char *pcSource) +{ + return strncpy(pcTarget, pcSource, strlen(pcSource)); +} + +/** + * @brief + * @details Finds the first sequence of characters in the string str1 that + * does not contain any character specified in str2. + * Returns the length of this first sequence of characters found that + * do not match with str2. + * @param[in] const WILC_Char *str1 + * @param[in] const WILC_Char *str2 + * @return WILC_Uint32 + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strcspn(const WILC_Char *str1, const WILC_Char *str2) +{ + return (WILC_Uint32)strcspn(str1, str2); +} +#if 0 +/** + * @brief + * @details Searches an internal array for the error number errnum and returns a pointer + * to an error message string. + * Returns a pointer to an error message string. + * @param[in] WILC_Sint32 errnum + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strerror(WILC_Sint32 errnum) +{ + return strerror(errnum); +} +#endif + +/** + * @brief + * @details Finds the first occurrence of the entire string str2 + * (not including the terminating null character) which appears in the string str1. + * Returns a pointer to the first occurrence of str2 in str1. + * If no match was found, then a null pointer is returned. + * If str2 points to a string of zero length, then the argument str1 is returned. + * @param[in] const WILC_Char *str1 + * @param[in] const WILC_Char *str2 + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strstr(const WILC_Char *str1, const WILC_Char *str2) +{ + return strstr(str1, str2); +} +#if 0 +/** + * @brief + * @details Parses the C string str interpreting its content as a floating point + * number and returns its value as a double. + * If endptr is not a null pointer, the function also sets the value pointed + * by endptr to point to the first character after the number. + * @param[in] const WILC_Char* str + * @param[in] WILC_Char** endptr + * @return WILC_Double + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Double WILC_StringToDouble(const WILC_Char *str, WILC_Char **endptr) +{ + return strtod (str, endptr); +} +#endif + +/** + * @brief Parses the C string str interpreting its content as an unsigned integral + * number of the specified base, which is returned as an unsigned long int value. + * @details The function first discards as many whitespace characters as necessary + * until the first non-whitespace character is found. + * Then, starting from this character, takes as many characters as possible + * that are valid following a syntax that depends on the base parameter, + * and interprets them as a numerical value. + * Finally, a pointer to the first character following the integer + * representation in str is stored in the object pointed by endptr. + * @param[in] const WILC_Char *str + * @param[in] WILC_Char **endptr + * @param[in] WILC_Sint32 base + * @return WILC_Uint32 + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_StringToUint32(const WILC_Char *str, WILC_Char **endptr, WILC_Sint32 base) +{ + return simple_strtoul(str, endptr, base); +} + +#endif + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_strutils.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_strutils.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_STRUTILS_H__ +#define __WILC_STRUTILS_H__ + +/*! + * @file wilc_strutils.h + * @brief Basic string utilities + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_STRING_UTILS +#error the feature CONFIG_WILC_STRING_UTILS must be supported to include this file +#endif + +/*! + * @brief Compares two memory buffers + * @param[in] pvArg1 pointer to the first memory location + * @param[in] pvArg2 pointer to the second memory location + * @param[in] u32Count the size of the memory buffers + * @return 0 if the 2 buffers are equal, 1 if pvArg1 is bigger than pvArg2, + * -1 if pvArg1 smaller than pvArg2 + * @note this function repeats the functionality of standard memcmp + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_memcmp(const void *pvArg1, const void *pvArg2, WILC_Uint32 u32Count); + +/*! + * @brief Internal implementation for memory copy + * @param[in] pvTarget the target buffer to which the data is copied into + * @param[in] pvSource pointer to the second memory location + * @param[in] u32Count the size of the data to copy + * @note this function should not be used directly, use WILC_memcpy instead + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_memcpy_INTERNAL(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count); + +/*! + * @brief Copies the contents of a memory buffer into another + * @param[in] pvTarget the target buffer to which the data is copied into + * @param[in] pvSource pointer to the second memory location + * @param[in] u32Count the size of the data to copy + * @return WILC_SUCCESS if copy is successfully handeled + * WILC_FAIL if copy failed + * @note this function repeats the functionality of standard memcpy, + * however memcpy is undefined if the two buffers overlap but this + * implementation will check for overlap and report error + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +static WILC_ErrNo WILC_memcpy(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count) +{ + if ( + (((WILC_Uint8 *)pvTarget <= (WILC_Uint8 *)pvSource) + && (((WILC_Uint8 *)pvTarget + u32Count) > (WILC_Uint8 *)pvSource)) + + || (((WILC_Uint8 *)pvSource <= (WILC_Uint8 *)pvTarget) + && (((WILC_Uint8 *)pvSource + u32Count) > (WILC_Uint8 *)pvTarget)) + ) { + /* ovelapped memory, return Error */ + return WILC_FAIL; + } else { + WILC_memcpy_INTERNAL(pvTarget, pvSource, u32Count); + return WILC_SUCCESS; + } +} + +/*! + * @brief Sets the contents of a memory buffer with the given value + * @param[in] pvTarget the target buffer which contsnts will be set + * @param[in] u8SetValue the value to be used + * @param[in] u32Count the size of the memory buffer + * @return value of pvTarget + * @note this function repeats the functionality of standard memset + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_memset(void *pvTarget, WILC_Uint8 u8SetValue, WILC_Uint32 u32Count); + +/*! + * @brief Concatenates the contents of 2 strings up to a given count + * @param[in] pcTarget the target string, its null character will be overwritten + * and contents of pcSource will be concatentaed to it + * @param[in] pcSource the source string the will be concatentaed + * @param[in] u32Count copying will proceed until a null character in pcSource + * is encountered or u32Count of bytes copied + * @return value of pcTarget + * @note this function repeats the functionality of standard strncat + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncat(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count); + +/*! + * @brief copies the contents of source string into the target string + * @param[in] pcTarget the target string buffer + * @param[in] pcSource the source string the will be copied + * @param[in] u32Count copying will proceed until a null character in pcSource + * is encountered or u32Count of bytes copied + * @return value of pcTarget + * @note this function repeats the functionality of standard strncpy + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncpy(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count); + +/*! + * @brief Compares two strings + * @details Compares 2 strings reporting which is bigger, WILC_NULL is considered + * the smallest string, then a zero length string then all other + * strings depending on thier ascii characters order + * @param[in] pcStr1 the first string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] pcStr2 the second string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2, + * -1 if pcStr1 smaller than pcStr2 + * @note this function repeats the functionality of standard strcmp + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strcmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2); + +/*! + * @brief Compares two strings up to u32Count characters + * @details Compares 2 strings reporting which is bigger, WILC_NULL is considered + * the smallest string, then a zero length string then all other + * strings depending on thier ascii characters order with small case + * converted to uppder case + * @param[in] pcStr1 the first string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] pcStr2 the second string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] u32Count copying will proceed until a null character in pcStr1 or + * pcStr2 is encountered or u32Count of bytes copied + * @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2, + * -1 if pcStr1 smaller than pcStr2 + * @author aabozaeid + * @date 7 Dec 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strncmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count); + +/*! + * @brief Compares two strings ignoring the case of its latin letters + * @details Compares 2 strings reporting which is bigger, WILC_NULL is considered + * the smallest string, then a zero length string then all other + * strings depending on thier ascii characters order with small case + * converted to uppder case + * @param[in] pcStr1 the first string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] pcStr2 the second string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2, + * -1 if pcStr1 smaller than pcStr2 + * @author syounan + * @date 1 Nov 2010 + * @version 2.0 + */ +WILC_Sint32 WILC_strcmp_IgnoreCase(const WILC_Char *pcStr1, const WILC_Char *pcStr2); + +/*! + * @brief Compares two strings ignoring the case of its latin letters up to + * u32Count characters + * @details Compares 2 strings reporting which is bigger, WILC_NULL is considered + * the smallest string, then a zero length string then all other + * strings depending on thier ascii characters order with small case + * converted to uppder case + * @param[in] pcStr1 the first string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] pcStr2 the second string, WILC_NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] u32Count copying will proceed until a null character in pcStr1 or + * pcStr2 is encountered or u32Count of bytes copied + * @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2, + * -1 if pcStr1 smaller than pcStr2 + * @author aabozaeid + * @date 7 Dec 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strncmp_IgnoreCase(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count); + +/*! + * @brief gets the length of a string + * @param[in] pcStr the string + * @return the length + * @note this function repeats the functionality of standard strlen + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strlen(const WILC_Char *pcStr); + +/*! + * @brief convert string to integer + * @param[in] pcStr the string + * @return the value of string + * @note this function repeats the functionality of the libc atoi + * @author bfahmy + * @date 28 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strtoint(const WILC_Char *pcStr); + +/*! + * @brief print a formatted string into a buffer + * @param[in] pcTarget the buffer where the resulting string is written + * @param[in] u32Size size of the output beffer including the \0 terminating + * character + * @param[in] pcFormat format of the string + * @return number of character written or would have been written if the + * string were not truncated + * @note this function repeats the functionality of standard snprintf + * @author syounan + * @date 1 Nov 2010 + * @version 2.0 + */ +WILC_Sint32 WILC_snprintf(WILC_Char *pcTarget, WILC_Uint32 u32Size, + const WILC_Char *pcFormat, ...); + + +#ifdef CONFIG_WILC_EXTENDED_STRING_OPERATIONS + + +/** + * @brief + * @details Searches for the first occurrence of the character c in the first n bytes + * of the string pointed to by the argument str. + * Returns a pointer pointing to the first matching character, + * or null if no match was found. + * @param[in] + * @return + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_memchr(const void *str, WILC_Char c, WILC_Sint32 n); + +/** + * @brief + * @details Searches for the first occurrence of the character c (an unsigned char) + * in the string pointed to by the argument str. + * The terminating null character is considered to be part of the string. + * Returns a pointer pointing to the first matching character, + * or null if no match was found. + * @param[in] + * @return + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strchr(const WILC_Char *str, WILC_Char c); + +/** + * @brief + * @details Appends the string pointed to by str2 to the end of the string pointed to by str1. + * The terminating null character of str1 is overwritten. + * Copying stops once the terminating null character of str2 is copied. If overlapping occurs, the result is undefined. + * The argument str1 is returned. + * @param[in] WILC_Char* str1, + * @param[in] WILC_Char* str2, + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strcat(WILC_Char *str1, const WILC_Char *str2); + + +/** + * @brief + * @details Copy pcSource to pcTarget + * @param[in] WILC_Char* pcTarget + * @param[in] const WILC_Char* pcSource + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strcpy(WILC_Char *pcTarget, const WILC_Char *pcSource); + + + +/** + * @brief + * @details Finds the first sequence of characters in the string str1 that + * does not contain any character specified in str2. + * Returns the length of this first sequence of characters found that + * do not match with str2. + * @param[in] const WILC_Char *str1 + * @param[in] const WILC_Char *str2 + * @return WILC_Uint32 + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strcspn(const WILC_Char *str1, const WILC_Char *str2); + + +/** + * @brief + * @details Searches an internal array for the error number errnum and returns a pointer + * to an error message string. + * Returns a pointer to an error message string. + * @param[in] WILC_Sint32 errnum + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strerror(WILC_Sint32 errnum); + +/** + * @brief + * @details Finds the first occurrence of the entire string str2 + * (not including the terminating null character) which appears in the string str1. + * Returns a pointer to the first occurrence of str2 in str1. + * If no match was found, then a null pointer is returned. + * If str2 points to a string of zero length, then the argument str1 is returned. + * @param[in] const WILC_Char *str1 + * @param[in] const WILC_Char *str2 + * @return WILC_Char* + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strstr(const WILC_Char *str1, const WILC_Char *str2); + +/** + * @brief + * @details Searches for the first occurrence of the character c (an unsigned char) + * in the string pointed to by the argument str. + * The terminating null character is considered to be part of the string. + * Returns a pointer pointing to the first matching character, + * or null if no match was found. + * @param[in] + * @return + * @note + * @author remil + * @date 3 Nov 2010 + * @version 1.0 + */ +WILC_Char *WILC_strchr(const WILC_Char *str, WILC_Char c); + + +/** + * @brief + * @details Parses the C string str interpreting its content as a floating point + * number and returns its value as a double. + * If endptr is not a null pointer, the function also sets the value pointed + * by endptr to point to the first character after the number. + * @param[in] const WILC_Char* str + * @param[in] WILC_Char** endptr + * @return WILC_Double + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Double WILC_StringToDouble(const WILC_Char *str, + WILC_Char **endptr); + + +/** + * @brief Parses the C string str interpreting its content as an unsigned integral + * number of the specified base, which is returned as an unsigned long int value. + * @details The function first discards as many whitespace characters as necessary + * until the first non-whitespace character is found. + * Then, starting from this character, takes as many characters as possible + * that are valid following a syntax that depends on the base parameter, + * and interprets them as a numerical value. + * Finally, a pointer to the first character following the integer + * representation in str is stored in the object pointed by endptr. + * @param[in] const WILC_Char *str + * @param[in] WILC_Char **endptr + * @param[in] WILC_Sint32 base + * @return WILC_Uint32 + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_StringToUint32(const WILC_Char *str, + WILC_Char **endptr, + WILC_Sint32 base); + + + +#endif + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_thread.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_thread.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_THREAD_FEATURE + + + +WILC_ErrNo WILC_ThreadCreate(WILC_ThreadHandle *pHandle, tpfWILC_ThreadFunction pfEntry, + void *pvArg, tstrWILC_ThreadAttrs *pstrAttrs) +{ + + + *pHandle = kthread_run((int (*)(void *))pfEntry, pvArg, "WILC_kthread"); + + + if (IS_ERR(*pHandle)) { + return WILC_FAIL; + } else { + return WILC_SUCCESS; + } + +} + +WILC_ErrNo WILC_ThreadDestroy(WILC_ThreadHandle *pHandle, + tstrWILC_ThreadAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + + kthread_stop(*pHandle); + return s32RetStatus; +} + + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_thread.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_thread.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_THREAD_H__ +#define __WILC_THREAD_H__ + +/*! + * @file wilc_thread.h + * @brief Thread OS Wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_THREAD_FEATURE +#error the feature WILC_OS_FEATURE_THREAD must be supported to include this file +#endif + +typedef void (*tpfWILC_ThreadFunction)(void *); + +typedef enum { + #ifdef CONFIG_WILC_THREAD_STRICT_PRIORITY + WILC_OS_THREAD_PIORITY_0 = 0, + WILC_OS_THREAD_PIORITY_1 = 1, + WILC_OS_THREAD_PIORITY_2 = 2, + WILC_OS_THREAD_PIORITY_3 = 3, + WILC_OS_THREAD_PIORITY_4 = 4, + #endif + + WILC_OS_THREAD_PIORITY_HIGH = 0, + WILC_OS_THREAD_PIORITY_NORMAL = 2, + WILC_OS_THREAD_PIORITY_LOW = 4 +} tenuWILC_ThreadPiority; + +/*! + * @struct WILC_ThreadAttrs + * @brief Thread API options + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +typedef struct { + /*!< + * stack size for use with WILC_ThreadCreate, default is WILC_OS_THREAD_DEFAULT_STACK + */ + WILC_Uint32 u32StackSize; + + /*!< + * piority for the thread, if WILC_OS_FEATURE_THREAD_STRICT_PIORITY is defined + * this value is strictly observed and can take a larger resolution + */ + tenuWILC_ThreadPiority enuPiority; + + #ifdef CONFIG_WILC_THREAD_SUSPEND_CONTROL + /*! + * if true the thread will be created suspended + */ + WILC_Bool bStartSuspended; + #endif + +} tstrWILC_ThreadAttrs; + +#define WILC_OS_THREAD_DEFAULT_STACK (10 * 1024) + +/*! + * @brief Fills the WILC_ThreadAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa WILC_ThreadAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ + +static void WILC_ThreadFillDefault(tstrWILC_ThreadAttrs *pstrAttrs) +{ + pstrAttrs->u32StackSize = WILC_OS_THREAD_DEFAULT_STACK; + pstrAttrs->enuPiority = WILC_OS_THREAD_PIORITY_NORMAL; + + #ifdef CONFIG_WILC_THREAD_SUSPEND_CONTROL + pstrAttrs->bStartSuspended = WILC_FALSE; + #endif +} + +/*! + * @brief Creates a new thread + * @details if the feature WILC_OS_FEATURE_THREAD_SUSPEND_CONTROL is + * defined and tstrWILC_ThreadAttrs.bStartSuspended is set to true + * the new thread will be created in suspended state, otherwise + * it will start executing immeadiately + * if the feature WILC_OS_FEATURE_THREAD_STRICT_PIORITY is defined + * piorities are strictly observed, otherwise the underlaying OS + * may not observe piorities + * @param[out] pHandle handle to the newly created thread object + * @param[in] pfEntry pointer to the entry point of the new thread + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_ThreadAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_ThreadCreate(WILC_ThreadHandle *pHandle, tpfWILC_ThreadFunction pfEntry, + void *pvArg, tstrWILC_ThreadAttrs *pstrAttrs); + +/*! + * @brief Destroys the Thread object + * @details This function is used for clean up and freeing any used resources + * This function will block until the destroyed thread exits cleanely, + * so, the thread code thould handle an exit case before this calling + * this function + * @param[in] pHandle handle to the thread object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_ThreadAttrs + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_ThreadDestroy(WILC_ThreadHandle *pHandle, + tstrWILC_ThreadAttrs *pstrAttrs); + +#ifdef CONFIG_WILC_THREAD_SUSPEND_CONTROL + +/*! + * @brief Suspends an executing Thread object + * @param[in] pHandle handle to the thread object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_ThreadAttrs + * @note Optional part, WILC_OS_FEATURE_THREAD_SUSPEND_CONTROL must be enabled + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_ThreadSuspend(WILC_ThreadHandle *pHandle, + tstrWILC_ThreadAttrs *pstrAttrs); + +/*! + * @brief Resumes a suspened Thread object + * @param[in] pHandle handle to the thread object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_ThreadAttrs + * @note Optional part, WILC_OS_FEATURE_THREAD_SUSPEND_CONTROL must be enabled + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_ThreadResume(WILC_ThreadHandle *pHandle, + tstrWILC_ThreadAttrs *pstrAttrs); + +#endif + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_time.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_time.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#define _CRT_SECURE_NO_DEPRECATE +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_TIME_FEATURE + + +WILC_Uint32 WILC_TimeMsec(void) +{ + WILC_Uint32 u32Time = 0; + struct timespec current_time; + + current_time = current_kernel_time(); + u32Time = current_time.tv_sec * 1000; + u32Time += current_time.tv_nsec / 1000000; + + + return u32Time; +} + + +#ifdef CONFIG_WILC_EXTENDED_TIME_OPERATIONS + +/** + * @brief + * @details function returns the implementation's best approximation to the + * processor time used by the process since the beginning of an + * implementation-dependent time related only to the process invocation. + * @return WILC_Uint32 + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_Clock() +{ + +} + + +/** + * @brief + * @details The difftime() function computes the difference between two calendar + * times (as returned by WILC_GetTime()): time1 - time0. + * @param[in] WILC_Time time1 + * @param[in] WILC_Time time0 + * @return WILC_Double + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Double WILC_DiffTime(WILC_Time time1, WILC_Time time0) +{ + +} + + + +/** + * @brief + * @details The gmtime() function converts the time in seconds since + * the Epoch pointed to by timer into a broken-down time, + * expressed as Coordinated Universal Time (UTC). + * @param[in] const WILC_Time* timer + * @return WILC_tm* + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_tm *WILC_GmTime(const WILC_Time *timer) +{ + +} + + +/** + * @brief + * @details The localtime() function converts the time in seconds since + * the Epoch pointed to by timer into a broken-down time, expressed + * as a local time. The function corrects for the timezone and any + * seasonal time adjustments. Local timezone information is used as + * though localtime() calls tzset(). + * @param[in] const WILC_Time* timer + * @return WILC_tm* + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_tm *WILC_LocalTime(const WILC_Time *timer) +{ + +} + + +/** + * @brief + * @details The mktime() function converts the broken-down time, + * expressed as local time, in the structure pointed to by timeptr, + * into a time since the Epoch value with the same encoding as that + * of the values returned by time(). The original values of the tm_wday + * and tm_yday components of the structure are ignored, and the original + * values of the other components are not restricted to the ranges described + * in the <time.h> entry. + * @param[in] WILC_tm* timer + * @return WILC_Time + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Time WILC_MkTime(WILC_tm *timer) +{ + +} + + +/** + * @brief + * @details The strftime() function places bytes into the array + * pointed to by s as controlled by the string pointed to by format. + * @param[in] WILC_Char* s + * @param[in] WILC_Uint32 maxSize + * @param[in] const WILC_Char* format + * @param[in] const WILC_tm* timptr + * @return WILC_Uint32 + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_StringFormatTime(WILC_Char *s, + WILC_Uint32 maxSize, + const WILC_Char *format, + const WILC_tm *timptr) +{ + +} + + +/** + * @brief The WILC_GetTime() function returns the value of time in seconds since the Epoch. + * @details The tloc argument points to an area where the return value is also stored. + * If tloc is a null pointer, no value is stored. + * @param[in] WILC_Time* tloc + * @return WILC_Time + * @note + * @author remil + * @date 11 Nov 2010 + * @version 1.0 + */ +WILC_Time WILC_GetTime(WILC_Time *tloc) +{ + +} + + +#endif +#endif + + Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_time.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_time.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_TIME_H__ +#define __WILC_TIME_H__ + +/*! +* @file wilc_time.h +* @brief Time retrival functionality +* @author syounan +* @sa wilc_oswrapper.h top level OS wrapper file +* @date 2 Sep 2010 +* @version 1.0 +*/ + +#ifndef CONFIG_WILC_TIME_FEATURE +#error the feature CONFIG_WILC_TIME_FEATURE must be supported to include this file +#endif + +/*! +* @struct WILC_ThreadAttrs +* @brief Thread API options +* @author syounan +* @date 2 Sep 2010 +* @version 1.0 +*/ +typedef struct { + /* a dummy type to prevent compile errors on empty structure*/ + WILC_Uint8 dummy; +} tstrWILC_TimeAttrs; + +typedef struct { + /*!< current year */ + WILC_Uint16 u16Year; + /*!< current month */ + WILC_Uint8 u8Month; + /*!< current day */ + WILC_Uint8 u8Day; + + /*!< current hour (in 24H format) */ + WILC_Uint8 u8Hour; + /*!< current minute */ + WILC_Uint8 u8Miute; + /*!< current second */ + WILC_Uint8 u8Second; + +} tstrWILC_TimeCalender; + +/*! +* @brief returns the number of msec elapsed since system start up +* @return number of msec elapsed singe system start up +* @note since this returned value is 32 bit, the caller must handle + wraparounds in values every about 49 of continous operations +* @author syounan +* @date 2 Sep 2010 +* @version 1.0 +*/ +WILC_Uint32 WILC_TimeMsec(void); + + + +#ifdef CONFIG_WILC_EXTENDED_TIME_OPERATIONS +/** +* @brief +* @details function returns the implementation's best approximation to the + processor time used by the process since the beginning of an + implementation-dependent time related only to the process invocation. +* @return WILC_Uint32 +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_Uint32 WILC_Clock(); + +/** +* @brief +* @details The difftime() function computes the difference between two calendar + times (as returned by WILC_GetTime()): time1 - time0. +* @param[in] WILC_Time time1 +* @param[in] WILC_Time time0 +* @return WILC_Double +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_Double WILC_DiffTime(WILC_Time time1, WILC_Time time0); + +/** +* @brief +* @details The gmtime() function converts the time in seconds since + the Epoch pointed to by timer into a broken-down time, + expressed as Coordinated Universal Time (UTC). +* @param[in] const WILC_Time* timer +* @return WILC_tm* +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_tm *WILC_GmTime(const WILC_Time *timer); + + +/** +* @brief +* @details The localtime() function converts the time in seconds since + the Epoch pointed to by timer into a broken-down time, expressed + as a local time. The function corrects for the timezone and any + seasonal time adjustments. Local timezone information is used as + though localtime() calls tzset(). +* @param[in] const WILC_Time* timer +* @return WILC_tm* +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_tm *WILC_LocalTime(const WILC_Time *timer); + + +/** +* @brief +* @details The mktime() function converts the broken-down time, + expressed as local time, in the structure pointed to by timeptr, + into a time since the Epoch value with the same encoding as that + of the values returned by time(). The original values of the tm_wday + and tm_yday components of the structure are ignored, and the original + values of the other components are not restricted to the ranges described + in the <time.h> entry. +* @param[in] WILC_tm* timer +* @return WILC_Time +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_Time WILC_MkTime(WILC_tm *timer); + + +/** +* @brief +* @details The strftime() function places bytes into the array + pointed to by s as controlled by the string pointed to by format. +* @param[in] WILC_Char* s +* @param[in] WILC_Uint32 maxSize +* @param[in] const WILC_Char* format +* @param[in] const WILC_tm* timptr +* @return WILC_Uint32 +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_Uint32 WILC_StringFormatTime(WILC_Char *s, + WILC_Uint32 maxSize, + const WILC_Char *format, + const WILC_tm *timptr); + + +/** +* @brief The WILC_GetTime() function returns the value of time in seconds since the Epoch. +* @details The tloc argument points to an area where the return value is also stored. + If tloc is a null pointer, no value is stored. +* @param[in] WILC_Time* tloc +* @return WILC_Time +* @note +* @author remil +* @date 11 Nov 2010 +* @version 1.0 +*/ +WILC_Time WILC_GetTime(WILC_Time *tloc); + +#endif + +#ifdef CONFIG_WILC_TIME_UTC_SINCE_1970 + +/*! +* @brief returns the number of seconds elapsed since 1970 (in UTC) +* @param[in] pstrAttrs Optional attributes, NULL for default +* @return number of seconds elapsed since 1970 (in UTC) +* @sa tstrWILC_TimeAttrs +* @author syounan +* @date 2 Sep 2010 +* @version 1.0 +*/ +WILC_Uint32 WILC_TimeUtcSince1970(tstrWILC_TimeAttrs *pstrAttrs); + +#endif + +#ifdef CONFIG_WILC_TIME_CALENDER + +/*! +* @brief gets the current calender time +* @return number of seconds elapsed since 1970 (in UTC) +* @param[out] ptstrCalender calender structure to be filled with time +* @param[in] pstrAttrs Optional attributes, NULL for default +* @sa WILC_ThreadAttrs +* @author syounan +* @date 2 Sep 2010 +* @version 1.0 +*/ +WILC_ErrNo WILC_TimeCalender(tstrWILC_TimeCalender *ptstrCalender, + tstrWILC_TimeAttrs *pstrAttrs); + +#endif + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_timer.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_timer.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ + +#include "wilc_oswrapper.h" + +#ifdef CONFIG_WILC_TIMER_FEATURE + + + +WILC_ErrNo WILC_TimerCreate(WILC_TimerHandle *pHandle, + tpfWILC_TimerFunction pfCallback, tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + setup_timer(pHandle, (void(*)(unsigned long))pfCallback, 0); + + return s32RetStatus; +} + +WILC_ErrNo WILC_TimerDestroy(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) { + s32RetStatus = del_timer_sync(pHandle); + pHandle = NULL; + } + + return s32RetStatus; +} + + +WILC_ErrNo WILC_TimerStart(WILC_TimerHandle *pHandle, WILC_Uint32 u32Timeout, + void *pvArg, tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) { + pHandle->data = (unsigned long)pvArg; + s32RetStatus = mod_timer(pHandle, (jiffies + msecs_to_jiffies(u32Timeout))); + } + return s32RetStatus; +} + +WILC_ErrNo WILC_TimerStop(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) + s32RetStatus = del_timer(pHandle); + + return s32RetStatus; +} + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_timer.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_timer.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +#ifndef __WILC_TIMER_H__ +#define __WILC_TIMER_H__ + +/*! + * @file wilc_timer.h + * @brief Timer (One Shot and Periodic) OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +#ifndef CONFIG_WILC_TIMER_FEATURE +#error the feature CONFIG_WILC_TIMER_FEATURE must be supported to include this file +#endif + +typedef void (*tpfWILC_TimerFunction)(void *); + +/*! + * @struct tstrWILC_TimerAttrs + * @brief Timer API options + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +typedef struct { + /*!< if set to WILC_TRUE the callback function will be called + * periodically. */ + #ifdef CONFIG_WILC_TIMER_PERIODIC + WILC_Bool bPeriodicTimer; + #endif + + /* a dummy member to avoid compiler errors*/ + WILC_Uint8 dummy; +} tstrWILC_TimerAttrs; + +/*! + * @brief Fills the WILC_TimerAttrs with default parameters + * @param[out] pstrAttrs structure to be filled + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ + +static void WILC_TimerFillDefault(tstrWILC_TimerAttrs *pstrAttrs) +{ + #ifdef CONFIG_WILC_TIMER_PERIODIC + pstrAttrs->bPeriodicTimer = WILC_FALSE; + #endif +} + + +/*! + * @brief Creates a new timer + * @details Timers are a useful utility to execute some callback function + * in the future. + * A timer object has 3 states : IDLE, PENDING and EXECUTING + * IDLE : initial timer state after creation, no execution for the + * callback function is planned + * PENDING : a request to execute the callback function is made + * using WILC_TimerStart. + * EXECUTING : the timer has expired and its callback is now + * executing, when execution is done the timer returns to PENDING + * if the feature CONFIG_WILC_TIMER_PERIODIC is enabled and + * the flag tstrWILC_TimerAttrs.bPeriodicTimer is set. otherwise the + * timer will return to IDLE + * @param[out] pHandle handle to the newly created timer object + * @param[in] pfEntry pointer to the callback function to be called when the + * timer expires + * the underlaying OS may put many restrictions on what can be + * called inside a timer's callback, as a general rule no blocking + * operations (IO or semaphore Acquision) should be perfomred + * It is recommended that the callback will be as short as possible + * and only flags other threads to do the actual work + * also it should be noted that the underlaying OS maynot give any + * guarentees on which contect this callback will execute in + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerCreate(WILC_TimerHandle *pHandle, + tpfWILC_TimerFunction pfCallback, tstrWILC_TimerAttrs *pstrAttrs); + + +/*! + * @brief Destroys a given timer + * @details This will destroy a given timer freeing any resources used by it + * if the timer was PENDING Then must be cancelled as well(i.e. + * goes to IDLE, same effect as calling WILC_TimerCancel first) + * if the timer was EXECUTING then the callback will be allowed to + * finish first then all resources are freed + * @param[in] pHandle handle to the timer object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerDestroy(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs); + +/*! + * @brief Starts a given timer + * @details This function will move the timer to the PENDING state until the + * given time expires (in msec) then the callback function will be + * executed (timer in EXECUTING state) after execution is dene the + * timer either goes to IDLE (if bPeriodicTimer==WILC_FALSE) or + * PENDING with same timeout value (if bPeriodicTimer==WILC_TRUE) + * @param[in] pHandle handle to the timer object + * @param[in] u32Timeout timeout value in msec after witch the callback + * function will be executed. Timeout value of 0 is not allowed for + * periodic timers + * @param[in] pstrAttrs Optional attributes, NULL for default, + * set bPeriodicTimer to run this timer as a periodic timer + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerStart(WILC_TimerHandle *pHandle, WILC_Uint32 u32Timeout, void *pvArg, + tstrWILC_TimerAttrs *pstrAttrs); + + +/*! + * @brief Stops a given timer + * @details This function will move the timer to the IDLE state cancelling + * any sheduled callback execution. + * if this function is called on a timer already in the IDLE state + * it will have no effect. + * if this function is called on a timer in EXECUTING state + * (callback has already started) it will wait until executing is + * done then move the timer to the IDLE state (which is trivial + * work if the timer is non periodic) + * @param[in] pHandle handle to the timer object + * @param[in] pstrAttrs Optional attributes, NULL for default, + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerStop(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs); + + + +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_type.h =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_type.h @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_type.h */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ +#ifndef WILC_TYPE_H +#define WILC_TYPE_H + +/******************************************** + * + * Type Defines + * + ********************************************/ +#ifdef WIN32 +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#else +#ifdef _linux_ +/*typedef unsigned char uint8_t; + * typedef unsigned short uint16_t; + * typedef unsigned long uint32_t;*/ +#include <stdint.h> +#else +#include "wilc_oswrapper.h" +#endif +#endif +#endif Index: linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_wfi_cfgoperations.c =================================================================== --- /dev/null +++ linux-3.18.13-rt10-r7s4/drivers/net/wireless/atmel/wilc1000/wilc_wfi_cfgoperations.c @ linux-3.18.13-rt10-r7s4/arch/arm/boot/dts/at91rm9200.dtsi:4 @ +/*! + * @file wilc_wfi_cfgopertaions.c + * @brief CFG80211 Function Implementation functionality + * @author aabouzaeid + * mabubakr + * mdaftedar + * zsalah + * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file + * @date 31 Aug 2010 + * @version 1.0 + */ + +#include "wilc_wfi_cfgoperations.h" +#include "wilc_wlan.c" +#ifdef WILC_SDIO +#include "linux_wlan_sdio.h" /* tony : for set_wiphy_dev() */ +#endif + + +#define IS_MANAGMEMENT 0x100 +#define IS_MANAGMEMENT_CALLBACK 0x080 +#define IS_MGMT_STATUS_SUCCES 0x040 +#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) + +extern void linux_wlan_free(void *vp); +extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic); +extern void linux_wlan_unlock(void *vp); +extern WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue); + +extern int mac_open(struct net_device *ndev); +extern int mac_close(struct net_device *ndev); + +tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; +WILC_Uint32 u32LastScannedNtwrksCountShadow; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +WILC_TimerHandle hDuringIpTimer; +#endif +WILC_TimerHandle hAgingTimer; +static WILC_Uint8 op_ifcs; +extern WILC_Uint8 u8ConnectedSSID[6]; + +/*BugID_5137*/ +WILC_Uint8 g_wilc_initialized = 1; +extern linux_wlan_t *g_linux_wlan; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_Bool g_obtainingIP; +#endif + +#define CHAN2G(_channel, _freq, _flags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +/*Frequency range for channels*/ +static struct ieee80211_channel WILC_WFI_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0),