summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitlab-ci.d/check-patch.py56
-rw-r--r--.gitlab-ci.yml119
-rw-r--r--Documentation/ABI/testing/sysfs-class-net-phydev12
-rw-r--r--Documentation/devicetree/bindings/display/bridge/lontium,lt8912.txt62
-rw-r--r--Documentation/devicetree/bindings/hwmon/sht3x.txt16
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt16
-rw-r--r--Documentation/devicetree/bindings/mfd/nxp,pca9450.txt10
-rw-r--r--Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt39
-rw-r--r--Documentation/devicetree/bindings/net/imx-dwmac.txt1
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt6
-rw-r--r--Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt3
-rw-r--r--Documentation/devicetree/bindings/usb/usb3503.txt7
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml2
-rw-r--r--Documentation/hwmon/lm75.rst6
-rw-r--r--Documentation/process/coding-style.rst23
-rw-r--r--arch/arm/boot/dts/Makefile24
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-aster.dts183
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-cam-eval-v3.dts280
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts143
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-iris-v2.dts182
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-iris.dts165
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-eval.dts184
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts203
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts359
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora.dts199
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi5
-rw-r--r--arch/arm/boot/dts/imx6qdl-apalis.dtsi645
-rw-r--r--arch/arm/boot/dts/imx6qdl-colibri.dtsi534
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-aster.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-aster.dtsi156
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-emmc-aster.dts17
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts17
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-emmc-iris-v2.dts17
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-emmc-iris.dts17
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi185
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts6
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi101
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-iris-v2.dts28
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-iris-v2.dtsi157
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-iris.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-iris.dtsi172
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-lcdif.dtsi200
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi167
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-wifi-aster.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts2
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-wifi-iris-v2.dts28
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-wifi-iris.dts20
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi167
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri.dtsi741
-rw-r--r--arch/arm/boot/dts/imx6ull.dtsi1
-rw-r--r--arch/arm/boot/dts/imx7-colibri-aster.dtsi146
-rw-r--r--arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi111
-rw-r--r--arch/arm/boot/dts/imx7-colibri-iris-v2.dtsi153
-rw-r--r--arch/arm/boot/dts/imx7-colibri-iris.dtsi151
-rw-r--r--arch/arm/boot/dts/imx7-colibri.dtsi573
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-aster.dts20
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts21
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dts8
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dts21
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-emmc-iris.dts21
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-emmc.dtsi60
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-eval-v3.dts56
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-iris-v2.dts64
-rw-r--r--arch/arm/boot/dts/imx7d-colibri-iris.dts33
-rw-r--r--arch/arm/boot/dts/imx7d-colibri.dtsi66
-rw-r--r--arch/arm/boot/dts/imx7d.dtsi152
-rw-r--r--arch/arm/boot/dts/imx7s-colibri-aster.dts16
-rw-r--r--arch/arm/boot/dts/imx7s-colibri-eval-v3.dts45
-rw-r--r--arch/arm/boot/dts/imx7s-colibri-iris-v2.dts59
-rw-r--r--arch/arm/boot/dts/imx7s-colibri-iris.dts16
-rw-r--r--arch/arm/boot/dts/imx7s-colibri.dtsi65
-rw-r--r--arch/arm/boot/dts/imx7s.dtsi166
-rw-r--r--arch/arm/configs/apalis_imx6_defconfig525
-rw-r--r--arch/arm/configs/colibri-imx6ull_defconfig496
-rw-r--r--arch/arm/configs/colibri_imx6_defconfig525
-rw-r--r--arch/arm/configs/colibri_imx7_defconfig511
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig10
-rw-r--r--arch/arm/configs/nit6xlite_defconfig303
-rw-r--r--arch/arm/kernel/reboot.c3
-rw-r--r--arch/arm/mach-imx/Kconfig3
-rw-r--r--arch/arm/mach-imx/Makefile4
-rw-r--r--arch/arm/mach-imx/busfreq-imx.c20
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6ul.c2
-rw-r--r--arch/arm/mach-imx/gpc.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c72
-rw-r--r--arch/arm/mach-imx/mach-imx7d.c42
-rw-r--r--arch/arm/mach-imx/mu.c9
-rw-r--r--arch/arm/mach-imx/pm-imx6.c47
-rw-r--r--arch/arm/mach-imx/pm-imx7.c10
-rw-r--r--arch/arm/mm/dma-mapping.c5
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile34
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi363
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi416
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi532
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi1844
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi48
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts17
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h24
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi152
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi65
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi75
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi95
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi1394
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi225
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi83
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi52
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dts18
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi83
-rwxr-xr-xarch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi1500
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi12
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-ixora-v1.1.dts20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts17
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.1.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.2.dts20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi363
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-eval.dts19
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.1.dts20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.2.dts20
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1.dtsi25
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-aster.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris-v2.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-dual-channel.dts102
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-single-channel.dts101
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi21
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri-aster.dtsi46
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri-eval-v3.dtsi184
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi41
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri-iris.dtsi201
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri.dtsi1474
-rw-r--r--arch/arm64/configs/defconfig731
-rw-r--r--arch/arm64/configs/toradex_defconfig1076
-rw-r--r--drivers/ata/ahci_imx.c17
-rw-r--r--drivers/clk/imx/clk-gate2.c2
-rw-r--r--drivers/clk/imx/clk-imx7d.c10
-rw-r--r--drivers/clk/imx/clk-imx8qxp.c1
-rw-r--r--drivers/clk/imx/clk-pfd.c2
-rw-r--r--drivers/clk/imx/clk-pllv3.c2
-rw-r--r--drivers/clk/imx/clk.h8
-rw-r--r--drivers/cpufreq/cpufreq-dt-platdev.c2
-rw-r--r--drivers/dma/pxp/pxp_dma_v3.c4
-rw-r--r--drivers/extcon/extcon-usb-gpio.c2
-rwxr-xr-xdrivers/firmware/imx/scu-pd.c2
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-fxl6408.c261
-rw-r--r--drivers/gpio/gpio-mxc.c100
-rw-r--r--drivers/gpu/drm/bridge/Kconfig10
-rw-r--r--drivers/gpu/drm/bridge/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c38
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c7
-rw-r--r--drivers/gpu/drm/bridge/lt8912.c730
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/Kconfig7
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c388
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h55
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c408
-rw-r--r--drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h33
-rw-r--r--drivers/gpu/drm/imx/dw_hdmi-imx.c9
-rw-r--r--drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx.h1
-rw-r--r--drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx8qm.c32
-rw-r--r--drivers/gpu/drm/imx/mhdp/cdns-mhdp-imxdrv.c29
-rw-r--r--drivers/gpu/drm/imx/sec_mipi_dsim-imx.c5
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_crtc.c8
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c73
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.h1
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c46
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c91
-rw-r--r--drivers/hwmon/lm75.c13
-rw-r--r--drivers/hwmon/sht3x.c28
-rw-r--r--drivers/i2c/busses/i2c-imx.c150
-rw-r--r--drivers/input/touchscreen/Kconfig23
-rw-r--r--drivers/input/touchscreen/Makefile2
-rw-r--r--drivers/input/touchscreen/ar1020-i2c.c500
-rw-r--r--drivers/input/touchscreen/fusion_F0710A.c507
-rw-r--r--drivers/input/touchscreen/fusion_F0710A.h88
-rw-r--r--drivers/media/platform/Kconfig11
-rw-r--r--drivers/media/platform/imx8/Kconfig14
-rw-r--r--drivers/media/platform/imx8/Makefile2
-rw-r--r--drivers/media/platform/imx8/ar0521.c3619
-rw-r--r--drivers/media/platform/imx8/ar0521.h291
-rw-r--r--drivers/media/platform/imx8/ar1335.c3625
-rw-r--r--drivers/media/platform/imx8/ar1335.h291
-rw-r--r--drivers/media/platform/imx8/ecam131_mcu_fw.txt2129
-rw-r--r--drivers/media/platform/imx8/ecam50_cam_fw.txt2146
-rw-r--r--drivers/media/platform/imx8/mcu_firmware.h91
-rw-r--r--drivers/media/platform/imx8/mcu_firmware_1335.h91
-rw-r--r--drivers/media/platform/mxc/capture/Kconfig28
-rw-r--r--drivers/media/platform/mxc/capture/Makefile12
-rw-r--r--drivers/media/platform/mxc/capture/adv7180.c263
-rw-r--r--drivers/media/platform/mxc/capture/adv7280.c1080
-rw-r--r--drivers/media/platform/mxc/capture/ipu_csi_enc.c2
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_enc.c16
-rw-r--r--drivers/media/platform/mxc/capture/max9526.c1153
-rw-r--r--drivers/media/platform/mxc/capture/mxc_mipi_csi.c59
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.c181
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.h9
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_mipi.c224
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_mipi_nv.c1509
-rw-r--r--drivers/media/platform/mxc/capture/tc358743_h2c.c3401
-rw-r--r--drivers/media/platform/mxc/output/mxc_vout.c3
-rw-r--r--drivers/mfd/pca9450.c15
-rw-r--r--drivers/mfd/stmpe.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c3
-rw-r--r--drivers/mmc/host/sdhci.c5
-rwxr-xr-xdrivers/mxc/hantro_845_h1/Kconfig1
-rw-r--r--drivers/mxc/ipu3/ipu_common.c6
-rw-r--r--drivers/mxc/mipi/mxc_mipi_csi2.c2
-rw-r--r--drivers/net/can/flexcan.c9
-rw-r--r--drivers/net/can/spi/Kconfig2
-rw-r--r--drivers/net/can/spi/Makefile2
-rw-r--r--drivers/net/can/spi/mcp25xxfd/Kconfig17
-rw-r--r--drivers/net/can/spi/mcp25xxfd/Makefile19
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.c286
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.h14
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c708
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.h56
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.c220
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.h45
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.c352
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.h16
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_id.h69
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.c749
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.h17
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_priv.h200
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.c522
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.h18
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.c716
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.h83
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.c498
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.h28
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.c392
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.h86
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.c88
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.h17
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.c112
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.h29
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.c75
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.h16
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.c241
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.h31
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.c73
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.h15
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_priv.h94
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_regs.h681
-rw-r--r--drivers/net/ethernet/freescale/fec.h10
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c112
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c30
-rw-r--r--drivers/net/phy/micrel.c96
-rw-r--r--drivers/net/phy/phy.c45
-rw-r--r--drivers/net/phy/phy_device.c76
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c5
-rw-r--r--drivers/of/irq.c1
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c251
-rw-r--r--drivers/pci/quirks.c24
-rw-r--r--drivers/phy/freescale/phy-fsl-samsung-hdmi.c18
-rw-r--r--drivers/power/reset/gpio-poweroff.c27
-rw-r--r--drivers/regulator/pca9450-regulator.c6
-rw-r--r--drivers/rpmsg/Kconfig8
-rw-r--r--drivers/rpmsg/imx_rpmsg.c4
-rw-r--r--drivers/rpmsg/imx_rpmsg_tty.c28
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c347
-rw-r--r--drivers/rtc/rtc-ds1307.c58
-rw-r--r--drivers/soc/imx/soc-imx-scu.c39
-rw-r--r--drivers/spi/spi-fsl-lpspi.c5
-rw-r--r--drivers/spi/spidev.c24
-rw-r--r--drivers/staging/media/imx/imx8-isi-cap.c155
-rw-r--r--drivers/staging/media/imx/imx8-mipi-csi2.c96
-rw-r--r--drivers/thermal/imx_thermal.c4
-rw-r--r--drivers/tty/serial/fsl_lpuart.c112
-rw-r--r--drivers/tty/serial/imx.c12
-rw-r--r--drivers/usb/chipidea/ci.h2
-rw-r--r--drivers/usb/chipidea/core.c96
-rw-r--r--drivers/usb/misc/usb3503.c49
-rw-r--r--drivers/usb/phy/phy-generic.c40
-rw-r--r--drivers/usb/phy/phy-generic.h1
-rw-r--r--drivers/video/backlight/pwm_bl.c2
-rw-r--r--drivers/video/fbdev/mxc/Makefile2
-rw-r--r--drivers/video/fbdev/mxc/ldb.c59
-rw-r--r--drivers/video/fbdev/mxc/mxc_hdmi.c148
-rw-r--r--drivers/video/fbdev/mxc/mxc_ipuv3_fb.c26
-rw-r--r--drivers/video/fbdev/mxc/mxc_lcdif.c6
-rw-r--r--drivers/video/fbdev/mxc/mxc_vdacif.c356
-rw-r--r--drivers/video/fbdev/mxsfb.c139
-rw-r--r--drivers/video/logo/Kconfig4
-rw-r--r--drivers/video/logo/Makefile2
-rw-r--r--drivers/video/logo/logo.c4
-rw-r--r--drivers/watchdog/imx_sc_wdt.c13
-rwxr-xr-xinclude/drm/bridge/cdns-mhdp.h1
-rw-r--r--include/linux/input/fusion_F0710A.h20
-rw-r--r--include/linux/linux_logo.h1
-rw-r--r--include/linux/mfd/pca9450.h4
-rw-r--r--include/linux/phy.h2
-rw-r--r--include/linux/pinctrl/devinfo.h4
-rw-r--r--include/linux/platform_data/usb3503.h2
-rw-r--r--include/linux/pm.h6
-rw-r--r--include/linux/sync.h390
-rw-r--r--include/media/v4l2-chip-ident.h3
-rw-r--r--include/media/v4l2-subdev.h9
-rw-r--r--include/video/mxc_hdmi.h7
-rw-r--r--net/bluetooth/hci_conn.c15
-rw-r--r--net/wireless/Kconfig4
-rwxr-xr-xscripts/checkpatch.pl38
-rw-r--r--sound/soc/codecs/Kconfig2
-rw-r--r--sound/soc/codecs/nau8822.c2
-rw-r--r--sound/soc/codecs/sgtl5000.c26
-rw-r--r--sound/soc/codecs/wm8904.c7
-rw-r--r--sound/soc/fsl/fsl_dsp.c74
-rw-r--r--sound/soc/fsl/fsl_sai.c24
-rw-r--r--sound/soc/fsl/fsl_sai.h3
-rw-r--r--sound/soc/fsl/fsl_spdif.c18
327 files changed, 53328 insertions, 2652 deletions
diff --git a/.gitlab-ci.d/check-patch.py b/.gitlab-ci.d/check-patch.py
new file mode 100755
index 000000000000..d828d78727b2
--- /dev/null
+++ b/.gitlab-ci.d/check-patch.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+#
+# check-patch.py: run checkpatch.pl across all commits in a branch
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+import os.path
+import sys
+import subprocess
+
+namespace = "linux-bsp"
+if len(sys.argv) >= 2:
+ namespace = sys.argv[1]
+
+cwd = os.getcwd()
+reponame = os.path.basename(cwd)
+if len(sys.argv) >= 3:
+ reponame = sys.argv[2]
+
+repourl = "https://gitlab.int.toradex.com/rd/%s/%s.git" % (namespace, reponame)
+masterbranch = "toradex_5.4-2.3.x-imx"
+check_patch_branch = "check-patch-%d" % os.getpid()
+rc = 0
+
+# GitLab CI environment does not give us any direct info about the
+# base for the user's branch. We thus need to figure out a common
+# ancestor between the user's branch and current git master.
+subprocess.check_call(["git", "remote", "add", check_patch_branch, repourl])
+try:
+ subprocess.check_call(["git", "fetch", check_patch_branch, masterbranch],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+
+ ancestor = subprocess.check_output(["git", "merge-base",
+ check_patch_branch + "/" + masterbranch, "HEAD"],
+ universal_newlines=True)
+
+ ancestor = ancestor.strip()
+
+ errors = False
+
+ print("\nChecking all commits since %s...\n" % ancestor)
+
+ ret = subprocess.run(["scripts/checkpatch.pl", "-g", ancestor + "..."])
+
+ if ret.returncode != 0:
+ print(ret)
+ print(" ❌ FAIL one or more commits failed scripts/checkpatch.pl")
+ rc = 1
+finally:
+ subprocess.check_call(["git", "remote", "rm", check_patch_branch])
+
+sys.exit(rc)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000000..b7415e856a1e
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,119 @@
+variables:
+# uncomment for the pipeline debug purpose
+# CI_DEBUG_TRACE: "true"
+ DOCKER_HOST: tcp://docker:2375
+ DOCKER_DRIVER: overlay2
+ DOCKER_TLS_CERTDIR: ""
+
+stages:
+ - check-patch
+ - build-kernel
+
+check_patch:
+ stage: check-patch
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
+ script: .gitlab-ci.d/check-patch.py
+ variables:
+ GIT_DEPTH: 1000
+ allow_failure: true
+
+32-bit-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
+ variables:
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make imx_v6_v7_defconfig
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+
+colibri-imx6ull-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
+ variables:
+ DEFCONFIG: colibri-imx6ull_defconfig
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ # Choose max kernel size that `ubinfo /dev/ubi0_0` reports
+ MAX_KERNEL_SIZE_B: 8507392
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+ KERNEL_SIZE=$(ls -la arch/arm/boot/zImage | awk '{print $5}')
+ echo "Kernel size is ${KERNEL_SIZE} bytes"
+ if [ $KERNEL_SIZE -ge $MAX_KERNEL_SIZE_B ];
+ then
+ echo "❌ Kernel exceeds the max size of ${MAX_KERNEL_SIZE_B}, failing CI pipeline";
+ exit 1
+ fi
+
+colibri-imx7-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
+ variables:
+ DEFCONFIG: colibri_imx7_defconfig
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ # Choose max kernel size that `ubinfo /dev/ubi0_0` reports
+ MAX_KERNEL_SIZE_B: 8507392
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+ KERNEL_SIZE=$(ls -la arch/arm/boot/zImage | awk '{print $5}')
+ echo "Kernel size is ${KERNEL_SIZE} bytes"
+ if [ $KERNEL_SIZE -ge $MAX_KERNEL_SIZE_B ];
+ then
+ echo "❌ Kernel exceeds the max size of ${MAX_KERNEL_SIZE_B}, failing CI pipeline";
+ exit 1
+ fi
+
+64-bit-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch64_arm_builder-bb6f84e
+ variables:
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm64/boot/dts/ -regextype posix-extended -regex "^.*\/fsl.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm64\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make defconfig
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+ make mrproper
diff --git a/Documentation/ABI/testing/sysfs-class-net-phydev b/Documentation/ABI/testing/sysfs-class-net-phydev
index 206cbf538b59..0a9943a37291 100644
--- a/Documentation/ABI/testing/sysfs-class-net-phydev
+++ b/Documentation/ABI/testing/sysfs-class-net-phydev
@@ -49,3 +49,15 @@ Description:
Boolean value indicating whether the PHY device is used in
standalone mode, without a net_device associated, by PHYLINK.
Attribute created only when this is the case.
+
+What: /sys/class/mdio_bus/<bus>/<device>/phy_dev_flags
+Date: March 2021
+KernelVersion: 5.13
+Contact: netdev@vger.kernel.org
+Description:
+ 32-bit hexadecimal number representing a bit mask of the
+ configuration bits passed from the consumer of the PHY
+ (Ethernet MAC, switch, etc.) to the PHY driver. The flags are
+ only used internally by the kernel and their placement are
+ not meant to be stable across kernel versions. This is intended
+ for facilitating the debugging of PHY drivers.
diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt8912.txt b/Documentation/devicetree/bindings/display/bridge/lontium,lt8912.txt
new file mode 100644
index 000000000000..b66eae06f194
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt8912.txt
@@ -0,0 +1,62 @@
+Lontium LT8912 MIPI-DSI to LVDS and HDMI/MHL bridge bindings
+
+Required properties and nodes:
+ - compatible: "lontium,lt8912"
+ - hpd-gpios: a GPIO spec for the hot-plug detect pin
+ - port: node referencing the MIPI-DSI source
+ - reg: i2c address of the bridge
+ - i2c-bus: phandle of an I2C controller used for register access
+ One of:
+ - ddc-i2c-bus: reference to a DDC-I2C bus for EDID retrival
+ - display-timings: hardcoded display timings if ddc-i2c-bus does not exist.
+ Refer to binding doc display-timing.txt for details
+
+Optional properties:
+ - reset-gpios: a GPIO spec for the reset pin
+
+Examples:
+&i2c1 {
+ lt8912@48 {
+ compatible = "lontium,lt8912";
+ ddc-i2c-bus = <&i2c0>;
+ hpd-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ reg = <0x48>;
+
+ port {
+ lt8912_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_out>;
+ };
+ };
+
+&i2c2 {
+ lt8912@48 {
+ compatible = "lontium,lt8912";
+ hpd-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ reg = <0x48>;
+
+ port {
+ lt8912_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_out>;
+ };
+ };
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <74250000>;
+ hactive = <1280>;
+ vactive = <720>;
+ hfront-porch = <110>;
+ hsync-len = <40>;
+ hback-porch = <220>;
+ vfront-porch = <5>;
+ vsync-len = <5>;
+ vback-porch = <20>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/hwmon/sht3x.txt b/Documentation/devicetree/bindings/hwmon/sht3x.txt
new file mode 100644
index 000000000000..e54327436605
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/sht3x.txt
@@ -0,0 +1,16 @@
+Sensirion SHT3x Humidity and Temperature Sensor
+
+Required node properties:
+- compatible: "sensirion,sht3x" or "sensirion,sts3x"
+- reg: I2C bus address of the device
+
+Optional properties:
+- sensirion,blocking-io: enable blocking mode on i2c
+- sensirion,no-high-precision: disable high accuracy
+
+Example sht3x node:
+
+sensor {
+ compatible = "sensirion,sht3x";
+ reg = <0x4a>;
+}
diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
index 2e1490a8fe74..192574f38ddb 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
@@ -3,15 +3,16 @@
Required Properties:
- compatible must be toradex,vf50-touchscreen
- io-channels: adc channels being used by the Colibri VF50 module
+ IIO ADC for Y-, X-, Y+, X+ connections
- xp-gpios: FET gate driver for input of X+
- xm-gpios: FET gate driver for input of X-
- yp-gpios: FET gate driver for input of Y+
- ym-gpios: FET gate driver for input of Y-
-- interrupts: pen irq interrupt for touch detection
-- pinctrl-names: "idle", "default", "gpios"
-- pinctrl-0: pinctrl node for pen/touch detection state pinmux
+- interrupts: pen irq interrupt for touch detection, signal from X plate
+- pinctrl-names: "idle", "default"
+- pinctrl-0: pinctrl node for pen/touch detection, pinctrl must provide
+ pull-up resistor on X+, X-.
- pinctrl-1: pinctrl node for X/Y and pressure measurement (ADC) state pinmux
-- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers
- vf50-ts-min-pressure: pressure level at which to stop measuring X/Y values
Example:
@@ -19,7 +20,7 @@ Example:
touchctrl: vf50_touchctrl {
compatible = "toradex,vf50-touchscreen";
io-channels = <&adc1 0>,<&adc0 0>,
- <&adc0 1>,<&adc1 2>;
+ <&adc0 1>,<&adc1 2>;
xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
@@ -27,8 +28,7 @@ Example:
interrupt-parent = <&gpio0>;
interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "idle","default","gpios";
- pinctrl-0 = <&pinctrl_touchctrl_idle>;
- pinctrl-1 = <&pinctrl_touchctrl_default>;
- pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+ pinctrl-0 = <&pinctrl_touchctrl_idle>, <&pinctrl_touchctrl_gpios> ;
+ pinctrl-1 = <&pinctrl_touchctrl_default>, <&pinctrl_touchctrl_gpios>;
vf50-ts-min-pressure = <200>;
};
diff --git a/Documentation/devicetree/bindings/mfd/nxp,pca9450.txt b/Documentation/devicetree/bindings/mfd/nxp,pca9450.txt
index f296c7d2e6ad..dd0fb3aec299 100644
--- a/Documentation/devicetree/bindings/mfd/nxp,pca9450.txt
+++ b/Documentation/devicetree/bindings/mfd/nxp,pca9450.txt
@@ -9,6 +9,15 @@ Required properties:
initialization data. Including 6 buck regulators
and 5 ldo regulators.
+Optional properties:
+ - i2c-lt-en : Sets I2C level translator enable in CONFIG2, valid:
+ 0x100 = Forced Disable
+ 0x101 = Enable only when STANDBY and RUN mode
+ 0x102 = Enable only when RUN mode
+ 0x103 = Forced enable
+ Any other value or if the property is missing CONFIG2
+ is not changed.
+
Example:
pmic: pca9450@25 {
reg = <0x25>;
@@ -16,6 +25,7 @@ Example:
/* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
pinctrl-0 = <&pinctrl_pmic>;
gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ i2c-lt-en = <0x101>;
regulators {
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt
new file mode 100644
index 000000000000..33c5c28f1455
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt
@@ -0,0 +1,39 @@
+* Microchip MCP2517 stand-alone CAN controller device tree bindings
+
+Required properties:
+ - compatible: Should be one of the following:
+ - "microchip,mcp2517fd" for MCP2517fd.
+ - "microchip,mcp2518fd" for MCP2518fd.
+ - reg: SPI chip select.
+ - clocks: The clock feeding the CAN controller.
+ - interrupt-parent: The parent interrupt controller.
+ - interrupts: Should contain IRQ line for the CAN controller.
+ - gpio-controller: Marks the device node as a GPIO controller
+
+Optional properties:
+ - vdd-supply: Regulator that powers the CAN controller.
+ - xceiver-supply: Regulator that powers the CAN transceiver.
+ - microchip,clock-out-div = <0|1|2|4|10>: Clock output pin divider
+ 0 = Start of Frame output
+ default: 10
+ - microchip,clock-allways-on: bool: Do not disable the clock if CAN
+ is inactive. Thus a clock on the
+ clko pin will not be stopped.
+ This results in a higher standby
+ current.
+ - microchip,clock-div2: bool: divide the internal clock by 2
+ - microchip,gpio-open-drain: bool: enable open-drain for all pins
+ (except cantx)
+ - microchip,gpio0-xstandby: bool: enable xstandby functionality on gpio 0
+
+Example:
+ can0: can@1 {
+ compatible = "microchip,mcp2517fd";
+ reg = <1>;
+ clocks = <&clk24m>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <13 0x8>;
+ vdd-supply = <&reg5v0>;
+ xceiver-supply = <&reg5v0>;
+ gpio-controller;
+ };
diff --git a/Documentation/devicetree/bindings/net/imx-dwmac.txt b/Documentation/devicetree/bindings/net/imx-dwmac.txt
index 402885fc0992..4a1cd825d676 100644
--- a/Documentation/devicetree/bindings/net/imx-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/imx-dwmac.txt
@@ -27,6 +27,7 @@ Required properties:
Optional properties:
- intf_mode: is optional for imx8dxl platform.
+- phy-supply: regulator that powers the Ethernet PHY.
- snps,rmii_refclk_ext: to select RMII reference clock from external.
Example:
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
index 8ac1d0851a0f..118d9852d3da 100644
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
@@ -47,10 +47,10 @@ PAD_CTL_PUE (1 << 4)
PAD_CTL_HYS (1 << 3)
PAD_CTL_SRE_SLOW (1 << 2)
PAD_CTL_SRE_FAST (0 << 2)
-PAD_CTL_DSE_X1 (0 << 0)
-PAD_CTL_DSE_X4 (1 << 0)
+PAD_CTL_DSE_X1 (min curr.) (0 << 0)
PAD_CTL_DSE_X2 (2 << 0)
-PAD_CTL_DSE_X6 (3 << 0)
+PAD_CTL_DSE_X4 (1 << 0)
+PAD_CTL_DSE_X6 (max curr.) (3 << 0)
Examples:
While iomuxc-lpsr is intended to be used by dedicated peripherals to take
diff --git a/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt b/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt
index 3e56c1b34a4c..2056e299a472 100644
--- a/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt
+++ b/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt
@@ -31,6 +31,9 @@ Optional properties:
- inactive-delay-ms: Delay (default 100) to wait after driving gpio inactive
- timeout-ms: Time to wait before asserting a WARN_ON(1). If nothing is
specified, 3000 ms is used.
+- force-mode: Force replacing pm_power_off kernel hook.
+ If this optional property is not specified, the driver will fail to
+ load if someone has registered the pm_power_off hook earlier.
Examples:
diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
index 057dd384d473..7ccedf6cc4d5 100644
--- a/Documentation/devicetree/bindings/usb/usb3503.txt
+++ b/Documentation/devicetree/bindings/usb/usb3503.txt
@@ -1,16 +1,21 @@
SMSC USB3503 High-Speed Hub Controller
Required properties:
-- compatible: Should be "smsc,usb3503" or "smsc,usb3503a".
+- compatible: Should be "smsc,usb3503" or "smsc,usb3503a" or "smsc,usb3803".
Optional properties:
- reg: Specifies the i2c slave address, it is required and should be 0x08
if I2C is used.
+- bypass-gpios: Should specify GPIO for bypass.
+ Follows the state of reset-gpios and is meant to be used with
+ usb3803's bypass pin.
- connect-gpios: Should specify GPIO for connect.
- disabled-ports: Should specify the ports unused.
'1' or '2' or '3' are available for this property to describe the port
number. 1~3 property values are possible to be described.
Do not describe this property if all ports have to be enabled.
+- non-removable-devices: Should specify the ports going to non removable
+ devices. See disabled-ports for the syntax.
- intn-gpios: Should specify GPIO for interrupt.
- reset-gpios: Should specify GPIO for reset.
- initial-mode: Should specify initial mode.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index fa5e531928df..b72195020009 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -545,6 +545,8 @@ patternProperties:
description: Logic PD, Inc.
"^longcheer,.*":
description: Longcheer Technology (Shanghai) Co., Ltd.
+ "^lontium,.*":
+ description: Lontium Semiconductor Corporation
"^lsi,.*":
description: LSI Corp. (LSI Logic)
"^lwn,.*":
diff --git a/Documentation/hwmon/lm75.rst b/Documentation/hwmon/lm75.rst
index e749f827c002..e804d242de77 100644
--- a/Documentation/hwmon/lm75.rst
+++ b/Documentation/hwmon/lm75.rst
@@ -93,9 +93,9 @@ Supported chips:
https://www.st.com/resource/en/datasheet/stlm75.pdf
- * Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75, TMP75B, TMP75C, TMP175, TMP275
+ * Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75, TMP75B, TMP75C, TMP175, TMP275, TMP1075
- Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp112', 'tmp175', 'tmp75', 'tmp75b', 'tmp75c', 'tmp275'
+ Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp112', 'tmp175', 'tmp75', 'tmp75b', 'tmp75c', 'tmp275', 'tmp1075'
Addresses scanned: none
@@ -119,6 +119,8 @@ Supported chips:
http://www.ti.com/product/tmp275
+ https://www.ti.com/product/TMP1075
+
* NXP LM75B, PCT2075
Prefix: 'lm75b', 'pct2075'
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index ada573b7d703..8a3b6485b33b 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -84,15 +84,20 @@ Get a decent editor and don't leave whitespace at the end of lines.
Coding style is all about readability and maintainability using commonly
available tools.
-The limit on the length of lines is 80 columns and this is a strongly
-preferred limit.
-
-Statements longer than 80 columns will be broken into sensible chunks, unless
-exceeding 80 columns significantly increases readability and does not hide
-information. Descendants are always substantially shorter than the parent and
-are placed substantially to the right. The same applies to function headers
-with a long argument list. However, never break user-visible strings such as
-printk messages, because that breaks the ability to grep for them.
+The preferred limit on the length of a single line is 80 columns.
+
+Statements longer than 80 columns should be broken into sensible chunks,
+unless exceeding 80 columns significantly increases readability and does
+not hide information.
+
+Descendants are always substantially shorter than the parent and are
+are placed substantially to the right. A very commonly used style
+is to align descendants to a function open parenthesis.
+
+These same rules are applied to function headers with a long argument list.
+
+However, never break user-visible strings such as printk messages because
+that breaks the ability to grep for them.
3) Placing Braces and Spaces
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0ec6f5b4e5a6..9d168005d52c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -401,7 +401,11 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-aristainetos_7.dtb \
imx6dl-aristainetos2_4.dtb \
imx6dl-aristainetos2_7.dtb \
+ imx6dl-colibri-aster.dtb \
+ imx6dl-colibri-cam-eval-v3.dtb \
imx6dl-colibri-eval-v3.dtb \
+ imx6dl-colibri-iris.dtb \
+ imx6dl-colibri-iris-v2.dtb \
imx6dl-cubox-i.dtb \
imx6dl-cubox-i-emmc-som-v15.dtb \
imx6dl-cubox-i-som-v15.dtb \
@@ -472,6 +476,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-apalis-eval.dtb \
imx6q-apalis-ixora.dtb \
imx6q-apalis-ixora-v1.1.dtb \
+ imx6q-apalis-ixora-v1.2.dtb \
imx6q-apf6dev.dtb \
imx6q-arm2.dtb \
imx6q-b450v3.dtb \
@@ -644,7 +649,17 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ull-9x9-evk-ldo.dtb \
imx6ull-9x9-evk-btwifi.dtb \
imx6ull-9x9-evk-btwifi-oob.dtb \
+ imx6ull-colibri-aster.dtb \
+ imx6ull-colibri-emmc-aster.dtb \
+ imx6ull-colibri-emmc-eval-v3.dtb \
+ imx6ull-colibri-emmc-iris.dtb \
+ imx6ull-colibri-emmc-iris-v2.dtb \
imx6ull-colibri-eval-v3.dtb \
+ imx6ull-colibri-iris.dtb \
+ imx6ull-colibri-iris-v2.dtb \
+ imx6ull-colibri-wifi-aster.dtb \
+ imx6ull-colibri-wifi-iris.dtb \
+ imx6ull-colibri-wifi-iris-v2.dtb \
imx6ull-colibri-wifi-eval-v3.dtb \
imx6ull-phytec-segin-ff-rdk-nand.dtb \
imx6ull-phytec-segin-ff-rdk-emmc.dtb \
@@ -655,6 +670,12 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ulz-14x14-evk-emmc.dtb
dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-cl-som-imx7.dtb \
+ imx7d-colibri-aster.dtb \
+ imx7d-colibri-iris.dtb \
+ imx7d-colibri-iris-v2.dtb \
+ imx7d-colibri-emmc-aster.dtb \
+ imx7d-colibri-emmc-iris.dtb \
+ imx7d-colibri-emmc-iris-v2.dtb \
imx7d-colibri-emmc-eval-v3.dtb \
imx7d-colibri-eval-v3.dtb \
imx7d-mba7.dtb \
@@ -663,6 +684,9 @@ dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-pico-hobbit.dtb \
imx7d-pico-pi.dtb \
imx7d-sbc-imx7.dtb \
+ imx7s-colibri-aster.dtb \
+ imx7s-colibri-iris.dtb \
+ imx7s-colibri-iris-v2.dtb \
imx7d-sdb.dtb \
imx7d-sdb-epdc.dtb \
imx7d-sdb-mipi-dsi.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-colibri-aster.dts b/arch/arm/boot/dts/imx6dl-colibri-aster.dts
new file mode 100644
index 000000000000..025c393d8b27
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-aster.dts
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2014-2018 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6DL/S on Colibri Aster Board";
+ compatible = "toradex,colibri_imx6dl-aster", "toradex,colibri_imx6dl", "fsl,imx6dl";
+
+ aliases {
+ i2c0 = &i2cddc;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ };
+
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ aliases {
+ /* the following, together with kernel patches, forces a fixed assignment
+ between device id and usdhc controller */
+ /* i.e. the eMMC on usdhc3 will be /dev/mmcblk0 */
+ mmc0 = &usdhc3; /* eMMC */
+ mmc1 = &usdhc1; /* MMC 4bit slot */
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ label = "Wake-Up";
+ gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+&ecspi4 {
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <
+ &gpio5 2 GPIO_ACTIVE_HIGH
+ &gpio5 4 GPIO_ACTIVE_HIGH
+ >;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_csi_gpio_2>;
+
+ spidev1: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <1>;
+ spi-max-frequency = <23000000>;
+ };
+};
+
+/*
+ * I2C: I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&iomuxc {
+ /*
+ * Mux all pins which are unused to be GPIOs
+ * so they are ready for export to user space
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_weim_gpio_1 &pinctrl_weim_gpio_2
+ &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
+ &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
+ &pinctrl_csi_gpio_1
+ &pinctrl_gpio_1
+ &pinctrl_gpio_2
+ &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1
+ >;
+
+ gpio {
+ pinctrl_gpios: gpios {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0 /* SODIMM 28 */
+ MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x1b0b0 /* SODIMM 30 */
+ >;
+ };
+
+ pinctrl_mxt_ts: mxt-ts {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x130b0 /* SODIMM 107 */
+ MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x130b0 /* SODIMM 106 */
+ >;
+ };
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
+/* MMC */
+&usdhc1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-colibri-cam-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-cam-eval-v3.dts
new file mode 100644
index 000000000000..2cdc6671683e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-cam-eval-v3.dts
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2014-2018 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6DL/S on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri_imx6dl-eval", "toradex,colibri_imx6dl", "fsl,imx6dl";
+
+ aliases {
+ i2c0 = &i2cddc;
+ i2c1 = &i2c2;
+ i2c2 = &i2c3;
+ };
+
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ aliases {
+ /* the following, together with kernel patches, forces a fixed assignment
+ between device id and usdhc controller */
+ /* i.e. the eMMC on usdhc3 will be /dev/mmcblk0 */
+ mmc0 = &usdhc3; /* eMMC */
+ mmc1 = &usdhc1; /* MMC 4bit slot */
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ label = "Wake-Up";
+ gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ v4l2_cap_0 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <1>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+/ {
+ clocks {
+ /* fixed crystal dedicated to mcp251x */
+ clk16m: clk16m {
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-output-names = "clk16m";
+ #clock-cells = <0>;
+ };
+ };
+};
+
+/* Colibri SPI */
+&ecspi4 {
+ mcp251x0: mcp251x@0 {
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 0x2>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+ };
+ /* To keep the CAN controller enabled by default,
+ * disable conflicting spidev. This spidev device
+ * enables with the devicetree overlay.
+ */
+ spidev0: spidev@0 {
+ status = "disabled";
+ };
+};
+
+&gpio3 {
+ camera_nreset {
+ gpio-hog;
+ gpios = <26 0>; /* SODIMM 71 */
+ output-high;
+ };
+};
+
+/*
+ * I2C: I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+
+ adv7280: adv7280@21 {
+ compatible = "adv7280";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_3p3v>;
+ PVDD-supply = <&reg_3p3v>;
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ status = "okay";
+ };
+
+ /* Video ADC on Analog Camera Module */
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ cvbs = <1>;
+ status = "disabled";
+ };
+ max9526: max9526@20 {
+ compatible = "maxim,max9526";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DVDDIO-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-suplsply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ cvbs = <1>;
+ status = "okay";
+ };
+};
+
+&iomuxc {
+ /*
+ * Mux all pins which are unused to be GPIOs
+ * so they are ready for export to user space
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_weim_gpio_1 &pinctrl_weim_gpio_2
+ &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
+ &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
+ &pinctrl_gpio_1
+ &pinctrl_gpio_2
+ &pinctrl_gpio_bl_on
+ &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1
+ >;
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+/* the PCAPs use SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm1, pwm4.
+ so if you enable one of the PCAP controllers disable the pwms */
+&pwm1 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+#if 0
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+#endif
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
+/* MMC */
+&usdhc1 {
+ status = "okay";
+};
+
+&weim {
+ status = "okay";
+ fsl,weim-cs-gpr = <&gpr>;
+ /* weim memory map: 32MB on CS0, 32MB on CS1, 32MB on CS2, 32MB on CS3 */
+ ranges = <0 0 0x08000000 0x02000000
+ 1 0 0x0a000000 0x02000000
+ 2 0 0x0c000000 0x02000000
+ 3 0 0x0e000000 0x02000000>;
+ /* SRAM on CS0 */
+ sram@0,0 {
+ compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram";
+ reg = <0 0 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00010081 0x00000000 0x04000000
+ 0x00000000 0x04000040 0x00000000>;
+ };
+ /* SRAM on CS1 */
+ sram@1,0 {
+ compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram";
+ reg = <1 0 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00010081 0x00000000 0x04000000
+ 0x00000000 0x04000040 0x00000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index 9a5d6c94cca4..dbee1c76f7b0 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -1,50 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
/*
- * Copyright 2014-2016 Toradex AG
+ * Copyright 2014-2020 Toradex
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
- *
- * 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
- * version 2 as published by the Free Software Foundation.
- *
- * 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 <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx6dl.dtsi"
#include "imx6qdl-colibri.dtsi"
@@ -69,6 +34,24 @@
rtc1 = &snvs_rtc;
};
+ aliases {
+ /*
+ * the following, together with kernel patches, forces a fixed
+ * assignment between device id and usdhc controller
+ * i.e. the eMMC on usdhc3 will be /dev/mmcblk0
+ */
+ mmc0 = &usdhc3; /* eMMC */
+ mmc1 = &usdhc1; /* MMC 4bit slot */
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -94,59 +77,10 @@
wakeup-source;
};
};
-
- lcd_display: disp0 {
- compatible = "fsl,imx-parallel-display";
- #address-cells = <1>;
- #size-cells = <0>;
- interface-pix-fmt = "bgr666";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu1_lcdif>;
- status = "okay";
-
- port@0 {
- reg = <0>;
-
- lcd_display_in: endpoint {
- remote-endpoint = <&ipu1_di0_disp0>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- lcd_display_out: endpoint {
- remote-endpoint = <&lcd_panel_in>;
- };
- };
- };
-
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
- backlight = <&backlight>;
-
- port {
- lcd_panel_in: endpoint {
- remote-endpoint = <&lcd_display_out>;
- };
- };
- };
-};
-
-&backlight {
- brightness-levels = <0 127 191 223 239 247 251 255>;
- default-brightness-level = <1>;
- status = "okay";
};
/* Colibri SSP */
&ecspi4 {
- status = "okay";
-
mcp251x0: mcp251x@0 {
compatible = "microchip,mcp2515";
reg = <0>;
@@ -156,10 +90,13 @@
spi-max-frequency = <10000000>;
status = "okay";
};
-};
-
-&hdmi {
- status = "okay";
+ /* To keep the CAN controller enabled by default,
+ * disable conflicting spidev. This spidev device
+ * enables with the devicetree overlay.
+ */
+ spidev0: spidev@0 {
+ status = "disabled";
+ };
};
/*
@@ -175,8 +112,25 @@
};
};
-&ipu1_di0_disp0 {
- remote-endpoint = <&lcd_display_in>;
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_weim_gpio_1 &pinctrl_weim_gpio_2
+ &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
+ &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
+ &pinctrl_csi_gpio_1
+ &pinctrl_gpio_1
+ &pinctrl_gpio_2
+ &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1
+ >;
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
};
&pwm1 {
@@ -218,6 +172,7 @@
&usbotg {
status = "okay";
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
};
/* Colibri MMC */
@@ -227,7 +182,7 @@
&weim {
status = "okay";
-
+ fsl,weim-cs-gpr = <&gpr>;
/* weim memory map: 32MB on CS0, CS1, CS2 and CS3 */
ranges = <0 0 0x08000000 0x02000000
1 0 0x0a000000 0x02000000
diff --git a/arch/arm/boot/dts/imx6dl-colibri-iris-v2.dts b/arch/arm/boot/dts/imx6dl-colibri-iris-v2.dts
new file mode 100644
index 000000000000..771696c09488
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-iris-v2.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6DL/S on Colibri Iris V2 Board";
+ compatible = "toradex,colibri_imx6dl-iris-v2", \
+ "toradex,colibri_imx6dl", "fsl,imx6dl";
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_vmmc>;
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+};
+
+/* Colibri SSP */
+&ecspi4 {
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
+ status = "okay";
+ };
+};
+
+&gpio2 {
+ /*
+ * uart_a_on_x13_enable turns the UART transceiver for UART_A on. If one
+ * wants to turn the transceiver off, that property has to be deleted
+ * and the gpio handled in userspace.
+ * The same applies to uart_b_c_on_x14_enable where the UART_B and
+ * UART_C transceiver is turned on.
+ */
+ uart_a_on_x13_enable {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_HIGH>; /* SODIMM 102 */
+ output-high;
+ };
+
+ uart_b_c_on_x14_enable {
+ gpio-hog;
+ gpios = <8 GPIO_ACTIVE_HIGH>; /* SODIMM 104 */
+ output-high;
+ };
+};
+
+/*
+ * I2C: I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&uart1 {
+ status = "okay";
+};
+
+/* Colibri UART_B */
+&uart2 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&uart3 {
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
+&usdhc1 {
+ cap-power-off-card;
+ /delete-property/ keep-power-in-suspend;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds_transceiver &pinctrl_gpio_iris>;
+
+ gpio {
+ pinctrl_lvds_transceiver: lvds-tx {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x0b030 /* SODIMM 55 */
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x03030 /* SODIMM 63 */
+ MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x03030 /* SODIMM 95 */
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x03030 /* SODIMM_99 */
+ >;
+ };
+
+ pinctrl_gpio_iris: gpio-iris {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0 /* SODIMM 98 */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0 /* SODIMM 133 */
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b0 /* SODIMM 103 */
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /* SODIMM 101 */
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x1b0b0 /* SODIMM 97 */
+ MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x1b0b0 /* SODIMM 85 */
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x1b0b0 /* SODIMM 79 */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /* SODIMM 45 */
+ >;
+ };
+ };
+
+ usdhc {
+ pinctrl_enable_3v3_vmmc: enable_3v3_vmmc {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x1b0b0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-colibri-iris.dts b/arch/arm/boot/dts/imx6dl-colibri-iris.dts
new file mode 100644
index 000000000000..19630add415a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-iris.dts
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2019 Toradex
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6DL/S on Colibri Iris Board";
+ compatible = "toradex,colibri_imx6dl-iris", \
+ "toradex,colibri_imx6dl", "fsl,imx6dl";
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+};
+
+/* Colibri SSP */
+&ecspi4 {
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
+ status = "okay";
+ };
+};
+
+/*
+ * I2C: I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&mxcfb1 {
+ status = "okay";
+};
+
+&mxcfb2 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_dte &pinctrl_uart1_ctrl
+ &pinctrl_uart1_forceoff>;
+};
+
+/* Colibri UART_B */
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_dte &pinctrl_uart23_forceoff>;
+};
+
+/* Colibri UART_C */
+&uart3 {
+ status = "okay";
+ /*
+ * Note that UART3 is on the same tranceiver as UART2 and this needs
+ * to be enabled with the pinmuxing &pinctrl_uart23_forceoff
+ */
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
+&usdhc1 {
+ status = "okay";
+};
+
+&gpio1 {
+ /*
+ * This turns the LVDS transceiver on. If one wants to turn the
+ * transceiver off, that property has to be deleted and the gpio handled
+ * in userspace.
+ */
+ lvds_tx_on {
+ gpio-hog;
+ gpios = <12 0>;
+ output-high;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_iris>;
+
+ gpio {
+ pinctrl_gpio_iris: gpio-iris {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0 /* SODIMM 98 */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0 /* SODIMM 133 */
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b0 /* SODIMM 103 */
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /* SODIMM 101 */
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x1b0b0 /* SODIMM 97 */
+ MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x1b0b0 /* SODIMM 85 */
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x1b0b0 /* SODIMM 79 */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /* SODIMM 45 */
+ >;
+ };
+ };
+
+ uart {
+ pinctrl_uart1_forceoff: uart1_forceoff {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart23_forceoff: uart23_forceoff {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x1b0b0
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts
index 0edd3043d9c1..b425d7a57209 100644
--- a/arch/arm/boot/dts/imx6q-apalis-eval.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
/*
- * Copyright 2014-2017 Toradex AG
+ * Copyright 2014-2020 Toradex
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
- *
- * 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
- * version 2 as published by the Free Software Foundation.
- *
- * 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/;
@@ -46,6 +10,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx6q.dtsi"
#include "imx6qdl-apalis.dtsi"
@@ -80,48 +45,6 @@
};
};
- lcd_display: disp0 {
- compatible = "fsl,imx-parallel-display";
- #address-cells = <1>;
- #size-cells = <0>;
- interface-pix-fmt = "rgb24";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu1_lcdif>;
- status = "okay";
-
- port@0 {
- reg = <0>;
-
- lcd_display_in: endpoint {
- remote-endpoint = <&ipu1_di1_disp1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- lcd_display_out: endpoint {
- remote-endpoint = <&lcd_panel_in>;
- };
- };
- };
-
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
- backlight = <&backlight>;
- power-supply = <&reg_3v3_sw>;
-
- port {
- lcd_panel_in: endpoint {
- remote-endpoint = <&lcd_display_out>;
- };
- };
- };
-
reg_pcie_switch: regulator-pcie-switch {
compatible = "regulator-fixed";
regulator-name = "pcie_switch";
@@ -140,13 +63,7 @@
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
-};
-&backlight {
- brightness-levels = <0 127 191 223 239 247 251 255>;
- default-brightness-level = <1>;
- power-supply = <&reg_3v3_sw>;
- status = "okay";
};
&can1 {
@@ -159,8 +76,26 @@
status = "okay";
};
-&hdmi {
+/* Apalis SPI1 */
+&ecspi1 {
status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&ecspi2 {
+ status = "okay";
+
+ spidev1: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
};
/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
@@ -185,14 +120,59 @@
*/
&i2c3 {
status = "okay";
-};
-&ipu1_di1_disp1 {
- remote-endpoint = <&lcd_display_in>;
-};
+ adv7280: adv7280@21 {
+ compatible = "adv7280";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_3p3v>;
+ PVDD-supply = <&reg_3p3v>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ status = "okay";
+ };
-&ldb {
- status = "okay";
+ /* Video ADC on Analog Camera Module */
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "disabled";
+ };
+
+ max9526: max9526@20 {
+ compatible = "maxim,max9526";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DVDDIO-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "okay";
+ };
};
&pcie {
@@ -200,7 +180,6 @@
pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- reset-gpio-active-high;
vpcie-supply = <&reg_pcie_switch>;
status = "okay";
};
@@ -221,11 +200,11 @@
status = "okay";
};
-&reg_usb_otg_vbus {
+&reg_usb_host_vbus {
status = "okay";
};
-&reg_usb_host_vbus {
+&reg_usb_otg_vbus {
status = "okay";
};
@@ -247,6 +226,11 @@
&uart2 {
status = "okay";
+#if 0
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+#endif
};
&uart4 {
@@ -269,9 +253,6 @@
/* MMC1 */
&usdhc1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit &pinctrl_mmc_cd>;
- cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -284,13 +265,10 @@
};
&iomuxc {
- /*
- * Mux the Apalis GPIOs
- */
+ /* Mux the Apalis GPIOs */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2
&pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4
- &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6
&pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8
>;
};
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
index b94bb687be6b..1382edb1d164 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
/*
- * Copyright 2014-2017 Toradex AG
+ * Copyright 2014-2020 Toradex
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
- *
- * 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
- * version 2 as published by the Free Software Foundation.
- *
- * 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/;
@@ -46,6 +10,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx6q.dtsi"
#include "imx6qdl-apalis.dtsi"
@@ -81,47 +46,6 @@
};
};
- lcd_display: disp0 {
- compatible = "fsl,imx-parallel-display";
- #address-cells = <1>;
- #size-cells = <0>;
- interface-pix-fmt = "rgb24";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu1_lcdif>;
- status = "okay";
-
- port@0 {
- reg = <0>;
-
- lcd_display_in: endpoint {
- remote-endpoint = <&ipu1_di1_disp1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- lcd_display_out: endpoint {
- remote-endpoint = <&lcd_panel_in>;
- };
- };
- };
-
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
- backlight = <&backlight>;
-
- port {
- lcd_panel_in: endpoint {
- remote-endpoint = <&lcd_display_out>;
- };
- };
- };
-
leds {
compatible = "gpio-leds";
@@ -148,24 +72,48 @@
gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
};
};
-};
-&backlight {
- brightness-levels = <0 127 191 223 239 247 251 255>;
- default-brightness-level = <1>;
- status = "okay";
+ reg_3v3_sw: regulator-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V_SW";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /delete-node/ v4l2_cap_1;
};
&can1 {
+ xceiver-supply = <&reg_3v3_sw>;
status = "okay";
};
&can2 {
+ xceiver-supply = <&reg_3v3_sw>;
+ status = "okay";
+};
+
+/* Apalis SPI1 */
+&ecspi1 {
status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
};
-&hdmi {
+/* Apalis SPI2 */
+&ecspi2 {
status = "okay";
+
+ spidev1: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
};
/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
@@ -185,14 +133,59 @@
*/
&i2c3 {
status = "okay";
-};
-&ipu1_di1_disp1 {
- remote-endpoint = <&lcd_display_in>;
-};
+ adv7280: adv7280@21 {
+ compatible = "adv7280";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_3p3v>;
+ PVDD-supply = <&reg_3p3v>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ status = "okay";
+ };
-&ldb {
- status = "okay";
+ /* Video ADC on Analog Camera Module */
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "disabled";
+ };
+
+ max9526: max9526@20 {
+ compatible = "maxim,max9526";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DVDDIO-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "okay";
+ };
};
&pcie {
@@ -200,7 +193,6 @@
pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- reset-gpio-active-high;
status = "okay";
};
@@ -220,11 +212,11 @@
status = "okay";
};
-&reg_usb_otg_vbus {
+&reg_usb_host_vbus {
status = "okay";
};
-&reg_usb_host_vbus {
+&reg_usb_otg_vbus {
status = "okay";
};
@@ -246,10 +238,21 @@
&uart2 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_dte &pinctrl_uart24_forceoff>;
+#if 0
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+#endif
};
&uart4 {
status = "okay";
+ /*
+ * note that uart4 is only working with pinctrl_uart24_forceoff that is
+ * already defined in &uart2
+ */
};
&uart5 {
@@ -270,19 +273,15 @@
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_mmc_cd>;
- cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
bus-width = <4>;
status = "okay";
};
&iomuxc {
- /*
- * Mux the Apalis GPIOs
- */
+ /* Mux the Apalis GPIOs */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2
&pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4
- &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6
&pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8
>;
@@ -294,4 +293,10 @@
MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
>;
};
+
+ pinctrl_uart24_forceoff: uart24_forceoff {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x1b0b0
+ >;
+ };
};
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
new file mode 100644
index 000000000000..5dc0d54f53b2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
+/*
+ * Copyright 2014-2020 Toradex
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "imx6q.dtsi"
+#include "imx6qdl-apalis.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX6Q/D Module on Ixora Carrier Board V1.2";
+ compatible = "toradex,apalis_imx6q-ixora-v1.2",
+ "toradex,apalis_imx6q-ixora", "toradex,apalis_imx6q",
+ "fsl,imx6q";
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c3;
+ i2c2 = &i2c2;
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ label = "Wake-Up";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ wakeup-source;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds_ixora>;
+
+ led4-green {
+ label = "LED_4_GREEN";
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ led4-red {
+ label = "LED_4_RED";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ led5-green {
+ label = "LED_5_GREEN";
+ gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ led5-red {
+ label = "LED_5_RED";
+ gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_vmmc>;
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+
+ reg_can1_supply: regulator-can1-supply {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can1_power>;
+ regulator-name = "can1_supply";
+ gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can2_supply: regulator-can2-supply {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can2_power>;
+ regulator-name = "can2_supply";
+ gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /delete-node/ v4l2_cap_1;
+};
+
+/* Apalis SPI1 */
+&ecspi1 {
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+&can1 {
+ status = "okay";
+ xceiver-supply = <&reg_can1_supply>;
+};
+
+&can2 {
+ status = "okay";
+ xceiver-supply = <&reg_can2_supply>;
+};
+
+/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
+&i2c1 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+/*
+ * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+
+ adv7280: adv7280@21 {
+ compatible = "adv7280";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_3p3v>;
+ PVDD-supply = <&reg_3p3v>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ status = "okay";
+ };
+
+ /* Video ADC on Analog Camera Module */
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "disabled";
+ };
+
+ max9526: max9526@20 {
+ compatible = "maxim,max9526";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DVDDIO-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "okay";
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
+ /* active-high meaning opposite of regular PERST# active-low polarity */
+ reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&reg_usb_otg_vbus {
+ status = "okay";
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&sound_spdif {
+ status = "okay";
+};
+
+&spdif {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_dte &pinctrl_uart24_forceoff>;
+#if 0
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+#endif
+};
+
+&uart4 {
+ status = "okay";
+ /*
+ * note that uart4 is only working with pinctrl_uart24_forceoff that is
+ * already defined in &uart2
+ */
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ status = "okay";
+};
+
+/* MMC1 */
+&usdhc1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_mmc_cd>;
+ pinctrl-1 = <&pinctrl_usdhc1_4bit_sleep &pinctrl_mmc_cd_sleep>;
+ bus-width = <4>;
+ cap-power-off-card;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ status = "okay";
+};
+
+&iomuxc {
+ /* Mux the Apalis GPIOs */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2
+ &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4
+ &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8
+ >;
+
+ pinctrl_leds_ixora: ledsixoragrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart24_forceoff: uart24_forceoff {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_3v3_vmmc: enable_3v3_vmmc {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_can1_power: enable_can1_power {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_can2_power: enable_can2_power {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_mmc_cd_sleep: gpiommccdgrpslp {
+ fsl,pins = <
+ /* MMC1 CD */
+ MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0
+ >;
+ };
+
+ pinctrl_usdhc1_4bit_sleep: usdhc1grp_4bit_sleep {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x3000
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x3000
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x3000
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x3000
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x3000
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x3000
+ >;
+ };
+
+};
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 302fd6adc8a7..7713d7eaedc0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
/*
- * Copyright 2014-2017 Toradex AG
+ * Copyright 2014-2020 Toradex
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
- *
- * 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
- * version 2 as published by the Free Software Foundation.
- *
- * 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/;
@@ -46,6 +10,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx6q.dtsi"
#include "imx6qdl-apalis.dtsi"
@@ -80,47 +45,6 @@
};
};
- lcd_display: disp0 {
- compatible = "fsl,imx-parallel-display";
- #address-cells = <1>;
- #size-cells = <0>;
- interface-pix-fmt = "rgb24";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ipu1_lcdif>;
- status = "okay";
-
- port@0 {
- reg = <0>;
-
- lcd_display_in: endpoint {
- remote-endpoint = <&ipu1_di1_disp1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- lcd_display_out: endpoint {
- remote-endpoint = <&lcd_panel_in>;
- };
- };
- };
-
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
- backlight = <&backlight>;
-
- port {
- lcd_panel_in: endpoint {
- remote-endpoint = <&lcd_display_out>;
- };
- };
- };
-
leds {
compatible = "gpio-leds";
@@ -147,24 +71,49 @@
gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
};
};
-};
-&backlight {
- brightness-levels = <0 127 191 223 239 247 251 255>;
- default-brightness-level = <1>;
- status = "okay";
+ reg_3v3_sw: regulator-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V_SW";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /delete-node/ v4l2_cap_1;
+ /delete-node/ v4l2_cap_2;
};
&can1 {
+ xceiver-supply = <&reg_3v3_sw>;
status = "okay";
};
&can2 {
+ xceiver-supply = <&reg_3v3_sw>;
status = "okay";
};
-&hdmi {
+/* Apalis SPI1 */
+&ecspi1 {
status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&ecspi2 {
+ status = "okay";
+
+ spidev1: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
};
/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
@@ -189,14 +138,59 @@
*/
&i2c3 {
status = "okay";
-};
-&ipu1_di1_disp1 {
- remote-endpoint = <&lcd_display_in>;
-};
+ adv7280: adv7280@21 {
+ compatible = "adv7280";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_3p3v>;
+ PVDD-supply = <&reg_3p3v>;
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ status = "okay";
+ };
-&ldb {
- status = "okay";
+ /* Video ADC on Analog Camera Module */
+ adv7180: adv7180@21 {
+ compatible = "adv,adv7180";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ PVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "disabled";
+ };
+
+ max9526: max9526@20 {
+ compatible = "maxim,max9526";
+ reg = <0x20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
+ clocks = <&clks IMX6QDL_CLK_CKO2>;
+ clock-names = "csi_mclk";
+ DVDDIO-supply = <&reg_3p3v>; /* 3.3v */
+ AVDD-supply = <&reg_3p3v>; /* 1.8v */
+ DVDD-supply = <&reg_3p3v>; /* 1.8v */
+ csi_id = <0>;
+ mclk = <24000000>;
+ mclk_source = <1>;
+ cvbs = <1>;
+ status = "okay";
+ };
};
&pcie {
@@ -204,7 +198,6 @@
pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- reset-gpio-active-high;
status = "okay";
};
@@ -224,11 +217,11 @@
status = "okay";
};
-&reg_usb_otg_vbus {
+&reg_usb_host_vbus {
status = "okay";
};
-&reg_usb_host_vbus {
+&reg_usb_otg_vbus {
status = "okay";
};
@@ -250,10 +243,21 @@
&uart2 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_dte &pinctrl_uart24_forceoff>;
+#if 0
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+#endif
};
&uart4 {
status = "okay";
+ /*
+ * note that uart4 is only working with pinctrl_uart24_forceoff that is
+ * already defined in &uart2
+ */
};
&uart5 {
@@ -283,7 +287,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2
&pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4
- &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6
&pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8
>;
@@ -295,4 +298,10 @@
MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
>;
};
+
+ pinctrl_uart24_forceoff: uart24_forceoff {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x1b0b0
+ >;
+ };
};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 2d3e137fc1fc..eed3f9d47f8c 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -236,8 +236,9 @@
interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_SATA>,
<&clks IMX6QDL_CLK_SATA_REF_100M>,
- <&clks IMX6QDL_CLK_AHB>;
- clock-names = "sata", "sata_ref", "ahb";
+ <&clks IMX6QDL_CLK_AHB>,
+ <&clks IMX6QDL_CLK_DUMMY>;
+ clock-names = "sata", "sata_ref", "ahb", "sata_ext";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index b165bd6ea53b..36419715dd43 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -46,22 +46,137 @@
/ {
model = "Toradex Apalis iMX6Q/D Module";
compatible = "toradex,apalis_imx6q", "fsl,imx6q";
-
/* Will be filled by the bootloader */
memory@10000000 {
device_type = "memory";
reg = <0x10000000 0>;
};
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ mxcfb2 = &mxcfb3;
+ mxcfb3 = &mxcfb4;
+ };
+
backlight: backlight {
compatible = "pwm-backlight";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_bl_on>;
- pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
enable-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ power-supply = <&reg_module_3v3>;
+ pwms = <&pwm4 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ clk_ov5640_osc: clk_ov5640_osc_int {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ /*
+ * HDMI_TX_DDC: I2C2_DDC_SDA/SCL on MXM3 205/207
+ */
+ i2cddc: i2c@0 {
+ compatible = "i2c-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_ddc>;
+ gpios = <
+ &gpio3 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */
+ &gpio2 30 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */
+ >;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ hdmi_ddc: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ status = "disabled";
+ };
+ };
+
+ lcd: lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <1>;
+ default_ifmt = "RGB24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+ status = "disabled";
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "ldb";
+ interface_pix_fmt = "RGB666";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="1920x1080M@60";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb3: fb@2 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB24";
+ mode_str ="CLAA-WVGA";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb4: fb@3 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "vdac";
+ interface_pix_fmt = "RGB565";
+ mode_str ="1024x768M@60";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
status = "disabled";
};
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_2p5v: regulator-2p5v {
+ compatible = "regulator-fixed";
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
reg_module_3v3: regulator-module-3v3 {
compatible = "regulator-fixed";
regulator-name = "+V3.3";
@@ -78,6 +193,26 @@
regulator-always-on;
};
+ reg_ov5640_1v8_d_o_vdd: regulator-ov5640-1v8-d-o-vdd {
+ compatible = "regulator-fixed";
+ regulator-name = "DOVDD/DVDD_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ /* Note: The CSI module uses on-board 3.3V_SW supply */
+ vin-supply = <&reg_module_3v3>;
+ };
+
+ reg_ov5640_2v8_a_vdd: regulator-ov5640-2v8-a-vdd {
+ compatible = "regulator-fixed";
+ regulator-name = "AVDD/AFVDD_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ /* Note: The CSI module uses on-board 3.3V_SW supply */
+ vin-supply = <&reg_module_3v3>;
+ };
+
reg_usb_otg_vbus: regulator-usb-otg-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -131,6 +266,14 @@
mux-ext-port = <4>;
};
+ sound_hdmi: sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi",
+ "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ status = "disabled";
+ };
+
sound_spdif: sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
@@ -139,6 +282,45 @@
spdif-out;
status = "disabled";
};
+
+ v4l2_cap_0 {
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <0>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+
+ v4l2_cap_1 { // second parallel camera
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <1>;
+ csi_id = <1>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+
+ v4l2_cap_2 { // mipi-csi2 camera
+ compatible = "fsl,imx6q-v4l2-capture";
+ ipu_id = <0>;
+ csi_id = <1>;
+ mclk_source = <0>;
+ status = "okay";
+ };
+
+ v4l2_out {
+ compatible = "fsl,mxc_v4l2_output";
+ status = "okay";
+ };
+
+ vdac: vdac@0 {
+ compatible = "fsl,vdac";
+ ipu_id = <1>;
+ disp_id = <0>;
+ default_ifmt = "RGB565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu2_vdac>;
+ status = "disabled";
+ };
};
&audmux {
@@ -148,14 +330,16 @@
};
&can1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_flexcan1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_flexcan1_default>;
+ pinctrl-1 = <&pinctrl_flexcan1_sleep>;
status = "disabled";
};
&can2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_flexcan2>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_flexcan2_default>;
+ pinctrl-1 = <&pinctrl_flexcan2_sleep>;
status = "disabled";
};
@@ -175,10 +359,203 @@
status = "disabled";
};
+&gpio1 {
+ gpio-line-names = "MXM3_84",
+ "MXM3_4",
+ "MXM3_15/GPIO7",
+ "MXM3_96",
+ "MXM3_37",
+ "",
+ "MXM3_17/GPIO8",
+ "MXM3_14",
+ "MXM3_12",
+ "MXM3_2",
+ "MXM3_184",
+ "MXM3_180",
+ "MXM3_178",
+ "MXM3_176",
+ "MXM3_188",
+ "MXM3_186",
+ "MXM3_160",
+ "MXM3_162",
+ "MXM3_150",
+ "MXM3_144",
+ "MXM3_154",
+ "MXM3_146",
+ "",
+ "",
+ "MXM3_72";
+};
+
+&gpio2 {
+ gpio-line-names = "MXM3_148",
+ "MXM3_152",
+ "MXM3_156",
+ "MXM3_158",
+ "MXM3_1/GPIO1",
+ "MXM3_3/GPIO2",
+ "MXM3_5/GPIO3",
+ "MXM3_7/GPIO4",
+ "MXM3_95",
+ "MXM3_6",
+ "MXM3_8",
+ "MXM3_123",
+ "MXM3_126",
+ "MXM3_128",
+ "MXM3_130",
+ "MXM3_132",
+ "MXM3_253",
+ "MXM3_251",
+ "MXM3_283",
+ "MXM3_281",
+ "MXM3_279",
+ "MXM3_277",
+ "MXM3_243",
+ "MXM3_235",
+ "MXM3_231",
+ "MXM3_229",
+ "MXM3_233",
+ "MXM3_198",
+ "MXM3_275",
+ "MXM3_273",
+ "MXM3_207",
+ "MXM3_122";
+};
+
+&gpio3 {
+ gpio-line-names = "MXM3_271",
+ "MXM3_269",
+ "MXM3_301",
+ "MXM3_299",
+ "MXM3_297",
+ "MXM3_295",
+ "MXM3_293",
+ "MXM3_291",
+ "MXM3_289",
+ "MXM3_287",
+ "MXM3_249",
+ "MXM3_247",
+ "MXM3_245",
+ "MXM3_286",
+ "MXM3_239",
+ "MXM3_35",
+ "MXM3_205",
+ "MXM3_203",
+ "MXM3_201",
+ "MXM3_116",
+ "MXM3_114",
+ "MXM3_262",
+ "MXM3_274",
+ "MXM3_124",
+ "MXM3_110",
+ "MXM3_120",
+ "MXM3_263",
+ "MXM3_265",
+ "",
+ "MXM3_135",
+ "MXM3_261",
+ "MXM3_259";
+};
+
+&gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_194",
+ "MXM3_136",
+ "MXM3_134",
+ "MXM3_140",
+ "MXM3_138",
+ "",
+ "MXM3_220",
+ "",
+ "",
+ "MXM3_18",
+ "MXM3_16",
+ "",
+ "",
+ "MXM3_214",
+ "MXM3_216",
+ "MXM3_164";
+};
+
+&gpio5 {
+ gpio-line-names = "MXM3_159",
+ "",
+ "",
+ "",
+ "MXM3_257",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_200",
+ "MXM3_196",
+ "MXM3_204",
+ "MXM3_202",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_191",
+ "MXM3_197",
+ "MXM3_77",
+ "MXM3_195",
+ "MXM3_221",
+ "MXM3_225",
+ "MXM3_223",
+ "MXM3_227",
+ "MXM3_209",
+ "MXM3_211",
+ "MXM3_118",
+ "MXM3_112",
+ "MXM3_187",
+ "MXM3_185";
+};
+
+&gpio6 {
+ gpio-line-names = "MXM3_183",
+ "MXM3_181",
+ "MXM3_179",
+ "MXM3_177",
+ "MXM3_175",
+ "MXM3_173",
+ "MXM3_255",
+ "MXM3_83",
+ "MXM3_91",
+ "MXM3_13/GPIO6",
+ "MXM3_11/GPIO5",
+ "MXM3_79",
+ "",
+ "",
+ "MXM3_190",
+ "MXM3_193",
+ "MXM3_89";
+};
+
+&gpio7 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_99",
+ "MXM3_85",
+ "MXM3_217",
+ "MXM3_215";
+};
+
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <&ethphy>;
phy-reset-duration = <10>;
phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
@@ -196,18 +573,53 @@
};
};
-&hdmi {
+&hdmi_cec {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hdmi_ddc>;
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
+ status = "disabled";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <0>;
+ status = "disabled";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "disabled";
};
/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
&i2c1 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_recovery>;
+ scl-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
+
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ fusion_f0710a: pcap@10 {
+ /* TouchRevolution Fusion 7 and 10 multi-touch controller */
+ compatible = "touchrevolution,fusion-f0710a";
+ reg = <0x10>;
+ gpios = <&gpio6 10 GPIO_ACTIVE_HIGH /* MXM3 11, Pen down interrupt */
+ &gpio6 9 GPIO_ACTIVE_HIGH /* MXM3 13, Reset */
+ >;
+ };
};
/*
@@ -216,13 +628,17 @@
*/
&i2c2 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_recovery>;
+ scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
pmic: pfuze100@8 {
compatible = "fsl,pfuze100";
reg = <0x08>;
+ fsl,pmic-stby-poweroff;
regulators {
sw1a_reg: sw1ab {
@@ -343,7 +759,7 @@
/* ADC converstion time: 80 clocks */
st,sample-time = <4>;
- stmpe_touchscreen {
+ stmpe_ts: stmpe_touchscreen {
compatible = "st,stmpe-ts";
/* 8 sample average control */
st,ave-ctrl = <3>;
@@ -358,6 +774,7 @@
st,settling = <3>;
/* 5 ms touch detect interrupt delay */
st,touch-det-delay = <5>;
+ status = "disabled";
};
stmpe_adc {
@@ -374,33 +791,191 @@
*/
&i2c3 {
clock-frequency = <100000>;
- pinctrl-names = "default", "recovery";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
pinctrl-1 = <&pinctrl_i2c3_recovery>;
scl-gpios = <&gpio3 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio3 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
+
+ ov5640_csi_cam: camera@3c {
+ compatible = "ovti,ov564x_mipi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cam_mclk>;
+ reg = <0x3c>;
+ /*
+ * By default use the internal on-cam clock source
+ * (Compatible with Toradex OV5640 v1.1b and later)
+ */
+ clocks = <&clk_ov5640_osc>;
+ clock-names = "csi_mclk";
+ DOVDD-supply = <&reg_ov5640_1v8_d_o_vdd>;
+ AVDD-supply = <&reg_ov5640_2v8_a_vdd>;
+ DVDD-supply = <&reg_ov5640_1v8_d_o_vdd>;
+ pwn-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+ rst-gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+ ipu_id = <0>;
+ csi_id = <1>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ status = "disabled";
+ };
+};
+
+&ldb {
+// split-mode;
+// dual-mode;
+
+ lvds-channel@0 {
+ reg = <0>;
+ fsl,data-mapping = "spwg"; /* "jeida"; */
+ fsl,data-width = <24>;
+ crtc = "ipu2-di1";
+ primary;
+
+ display-timings {
+ native-mode = <&timing_xga>;
+ /* LDB-AM-800600LTNQW-A0H */
+ timing_svga: 800x600 {
+ clock-frequency = <55000000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <112>;
+ hfront-porch = <32>;
+ vback-porch = <3>;
+ vfront-porch = <17>;
+ hsync-len = <80>;
+ vsync-len = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ /* Standard XGA timing */
+ timing_xga: 1024x768 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <160>;
+ hfront-porch = <24>;
+ vback-porch = <29>;
+ vfront-porch = <3>;
+ hsync-len = <136>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ timing_wxga: 1280x800 {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ /* LTTD1280800101-L4WH-CT1, note that it needs
+ fsl,data-mapping = "spwg"; fsl,data-width = <24>; */
+ timing_wxga1: 1280x800-1 {
+ clock-frequency = <71100000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <60>;
+ hfront-porch = <60>;
+ vback-porch = <7>;
+ vfront-porch = <7>;
+ hsync-len = <40>;
+ vsync-len = <9>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ timing_fullhd: 1920x1080 {
+ clock-frequency = <138500000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hback-porch = <80>;
+ hfront-porch = <48>;
+ vback-porch = <23>;
+ vfront-porch = <3>;
+ hsync-len = <32>;
+ vsync-len = <5>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ reg = <1>;
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ crtc = "ipu1-di0";
+
+ display-timings {
+/* native-mode = <&timing_svga_ch2>;*/
+ /* LDB-AM-800600LTNQW-A0H */
+ timing_svga_ch2: 800x600 {
+ clock-frequency = <55000000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <112>;
+ hfront-porch = <32>;
+ vback-porch = <3>;
+ vfront-porch = <17>;
+ hsync-len = <80>;
+ vsync-len = <4>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&mipi_csi {
+ csi_id = <1>;
+ ipu_id = <0>;
+ lanes = <2>;
+ v_channel = <0>;
+
+ status = "disabled";
+};
+
+&pcie {
+ /* Gen2 does not work on Apalis iMX6 */
+ fsl,max-link-speed = <1>;
};
&pwm1 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "disabled";
};
&pwm2 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "disabled";
};
&pwm3 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "disabled";
};
&pwm4 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
status = "disabled";
@@ -456,7 +1031,8 @@
/* MMC1 */
&usdhc1 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit>;
+ pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit &pinctrl_mmc_cd>;
+ cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
vqmmc-supply = <&reg_module_3v3>;
bus-width = <8>;
disable-wp;
@@ -599,19 +1175,32 @@
>;
};
- pinctrl_flexcan1: flexcan1grp {
+ pinctrl_flexcan1_default: flexcan1defgrp {
fsl,pins = <
MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
>;
};
- pinctrl_flexcan2: flexcan2grp {
+ pinctrl_flexcan1_sleep: flexcan1slpgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x0
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0
+ >;
+ };
+
+ pinctrl_flexcan2_default: flexcan2defgrp {
fsl,pins = <
MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
>;
};
+ pinctrl_flexcan2_sleep: flexcan2slpgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x0
+ >;
+ };
pinctrl_gpio_bl_on: gpioblon {
fsl,pins = <
@@ -632,6 +1221,14 @@
>;
};
+ pinctrl_i2c_ddc: gpioi2cddcgrp {
+ fsl,pins = <
+ /* DDC bitbang */
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
+ MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+ >;
+ };
+
pinctrl_hdmi_ddc: hdmiddcgrp {
fsl,pins = <
MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
@@ -641,8 +1238,15 @@
pinctrl_i2c1: i2c1grp {
fsl,pins = <
- MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c1_recovery: i2c1recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x4001b8b1
>;
};
@@ -653,6 +1257,13 @@
>;
};
+ pinctrl_i2c2_recovery: i2c2recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x4001b8b1
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index 019dda6b88ad..4f0670bb05ba 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -47,12 +47,19 @@
model = "Toradex Colibri iMX6DL/S Module";
compatible = "toradex,colibri_imx6dl", "fsl,imx6dl";
+ aliases {
+ mxcfb0 = &mxcfb1;
+ mxcfb1 = &mxcfb2;
+ };
+
backlight: backlight {
compatible = "pwm-backlight";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_bl_on>;
- pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
enable-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* Colibri BL_ON */
+ pwms = <&pwm3 0 6666667 PWM_POLARITY_INVERTED>;
status = "disabled";
};
@@ -83,6 +90,77 @@
status = "disabled";
};
+ reg_2p5v: 2p5v {
+ compatible = "regulator-fixed";
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+/*
+ * DDC_I2C: I2C2_SDA/SCL on X2 16/15
+ */
+ i2cddc: i2c@0 {
+ compatible = "i2c-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_ddc>;
+ gpios = <&gpio4 13 0 /* sda */
+ &gpio4 12 0 /* scl */
+ >;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ /* Extension connector pin 15/16 */
+ hdmi_ddc: edid@50 {
+ compatible = "fsl,imx6-hdmi-i2c";
+ reg = <0x50>;
+ status = "disabled";
+ };
+ };
+
+ lcd: lcd@0 {
+ compatible = "fsl,lcd";
+ ipu_id = <0>;
+ disp_id = <0>;
+ default_ifmt = "RGB666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+ status = "disabled";
+ };
+
+ mxcfb1: fb@0 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "lcd";
+ interface_pix_fmt = "RGB666";
+ mode_str ="640x480M@60";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
+ mxcfb2: fb@1 {
+ compatible = "fsl,mxc_sdc_fb";
+ disp_dev = "hdmi";
+ interface_pix_fmt = "RGB24";
+ mode_str ="640x480M@60";
+ default_bpp = <16>;
+ int_clk = <0>;
+ late_init = <0>;
+ status = "disabled";
+ };
+
sound {
compatible = "fsl,imx-audio-sgtl5000";
model = "imx6dl-colibri-sgtl5000";
@@ -97,6 +175,15 @@
mux-ext-port = <5>;
};
+ /* On-module HDMI interface */
+ sound_hdmi: sound-hdmi {
+ compatible = "fsl,imx6q-audio-hdmi",
+ "fsl,imx-audio-hdmi";
+ model = "imx-audio-hdmi";
+ hdmi-controller = <&hdmi_audio>;
+ status = "disabled";
+ };
+
/* Optional S/PDIF in on SODIMM 88 and out on SODIMM 90, 137 or 168 */
sound_spdif: sound-spdif {
compatible = "fsl,imx-audio-spdif";
@@ -106,6 +193,11 @@
spdif-out;
status = "disabled";
};
+
+ v4l2_out {
+ compatible = "fsl,mxc_v4l2_output";
+ status = "okay";
+ };
};
&audmux {
@@ -133,7 +225,13 @@
cs-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>;
- status = "disabled";
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
+ };
};
&fec {
@@ -154,9 +252,233 @@
};
};
-&hdmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hdmi_ddc>;
+&gpio1 {
+ gpio-line-names = "",
+ "SODIMM_67", /* Can be SODIMM_135, see page 4 */
+ "SODIMM_180",
+ "SODIMM_196",
+ "SODIMM_174",
+ "SODIMM_176",
+ "SODIMM_194",
+ "SODIMM_55",
+ "SODIMM_63",
+ "SODIMM_28",
+ "SODIMM_93",
+ "SODIMM_69",
+ "SODIMM_99",
+ "SODIMM_130",
+ "SODIMM_106",
+ "SODIMM_98",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_190",
+ "SODIMM_51",
+ "SODIMM_47",
+ "SODIMM_53",
+ "",
+ "SODIMM_22";
+};
+
+&gpio2 {
+ gpio-line-names = "SODIMM_132",
+ "SODIMM_134",
+ "SODIMM_135", /* Can be 67, see page 4 */
+ "SODIMM_133",
+ "SODIMM_102",
+ "SODIMM_43",
+ "SODIMM_127",
+ "SODIMM_37",
+ "SODIMM_104",
+ "SODIMM_59",
+ "SODIMM_30",
+ "SODIMM_100",
+ "SODIMM_38",
+ "SODIMM_34",
+ "SODIMM_32",
+ "SODIMM_36",
+ "SODIMM_59",
+ "SODIMM_67",
+ "SODIMM_97",
+ "SODIMM_79",
+ "SODIMM_103",
+ "SODIMM_101",
+ "SODIMM_45",
+ "SODIMM_105",
+ "SODIMM_107",
+ "SODIMM_91",
+ "SODIMM_89",
+ "SODIMM_150",
+ "SODIMM_126",
+ "SODIMM_128",
+ "",
+ "SODIMM_94";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_111",
+ "SODIMM_113",
+ "SODIMM_115",
+ "SODIMM_117",
+ "SODIMM_119",
+ "SODIMM_121",
+ "SODIMM_123",
+ "SODIMM_125",
+ "SODIMM_110",
+ "SODIMM_112",
+ "SODIMM_114",
+ "SODIMM_116",
+ "SODIMM_118",
+ "SODIMM_120",
+ "SODIMM_122",
+ "SODIMM_124",
+ "",
+ "SODIMM_96",
+ "SODIMM_77",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_88",
+ "SODIMM_90",
+ "SODIMM_31",
+ "SODIMM_23",
+ "SODIMM_29",
+ "SODIMM_71",
+ "SODIMM_73",
+ "SODIMM_92",
+ "SODIMM_81",
+ "SODIMM_131",
+ "SODIMM_129";
+};
+
+&gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_168",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_184",
+ "SODIMM_186",
+ "HDMI_15",
+ "HDMI_16",
+ "SODIMM_178",
+ "SODIMM_188",
+ "SODIMM_56",
+ "SODIMM_44",
+ "SODIMM_68",
+ "SODIMM_82",
+ "SODIMM_24",
+ "SODIMM_76",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_95",
+ "",
+ "SODIMM_86",
+ "",
+ "SODIMM_65",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_57",
+ "SODIMM_61",
+ "SODIMM_136",
+ "SODIMM_138",
+ "SODIMM_140",
+ "SODIMM_142",
+ "SODIMM_144",
+ "SODIMM_146",
+ "SODIMM_172",
+ "SODIMM_170",
+ "SODIMM_149",
+ "SODIMM_151",
+ "SODIMM_153",
+ "SODIMM_155",
+ "SODIMM_157",
+ "SODIMM_159",
+ "SODIMM_161",
+ "SODIMM_163",
+ "SODIMM_33",
+ "SODIMM_35",
+ "SODIMM_165",
+ "SODIMM_167";
+};
+
+&gpio6 {
+ gpio-line-names = "SODIMM_169",
+ "SODIMM_171",
+ "SODIMM_173",
+ "SODIMM_175",
+ "SODIMM_177",
+ "SODIMM_179",
+ "SODIMM_85",
+ "SODIMM_166",
+ "SODIMM_160",
+ "SODIMM_162",
+ "SODIMM_158",
+ "SODIMM_164",
+ "",
+ "",
+ "SODIMM_156",
+ "SODIMM_75",
+ "SODIMM_154",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_152";
+};
+
+&gpio7 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_19",
+ "SODIMM_21",
+ "",
+ "SODIMM_137";
+};
+
+&hdmi_core {
+ ipu_id = <0>;
+ disp_id = <1>;
+ status = "disabled";
+};
+
+&hdmi_video {
+ fsl,phy_reg_vlev = <0x0294>;
+ fsl,phy_reg_cksymtx = <0x800d>;
status = "disabled";
};
@@ -166,13 +488,17 @@
*/
&i2c2 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_recovery>;
+ scl-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio3 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
pmic: pfuze100@8 {
compatible = "fsl,pfuze100";
reg = <0x08>;
+ fsl,pmic-stby-poweroff;
regulators {
sw1a_reg: sw1ab {
@@ -226,7 +552,12 @@
regulator-always-on;
};
- /* vgen3: unused */
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
vgen4_reg: vgen4 {
regulator-min-microvolt = <1800000>;
@@ -282,7 +613,7 @@
/* ADC converstion time: 80 clocks */
st,sample-time = <4>;
- stmpe_touchscreen {
+ stmpe_ts: stmpe_touchscreen {
compatible = "st,stmpe-ts";
/* 8 sample average control */
st,ave-ctrl = <3>;
@@ -297,6 +628,7 @@
st,settling = <3>;
/* 5 ms touch detect interrupt delay */
st,touch-det-delay = <5>;
+ status = "disabled";
};
stmpe_adc {
@@ -312,40 +644,64 @@
*/
&i2c3 {
clock-frequency = <100000>;
- pinctrl-names = "default", "recovery";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
pinctrl-1 = <&pinctrl_i2c3_recovery>;
scl-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "disabled";
+
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_conn>;
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <24 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 */
+ reset-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */
+ status = "disabled";
+ };
+
+ fusion_f0710a: touchscreen@10 {
+ /* TouchRevolution Fusion 7 and 10 multi-touch controller */
+ compatible = "touchrevolution,fusion-f0710a";
+ reg = <0x10>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_adap>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH /* SODIMM 28, Pen intr */
+ &gpio2 10 GPIO_ACTIVE_LOW /* SODIMM 30, Reset */
+ >;
+ status = "disabled";
+ };
};
/* Colibri PWM<B> */
&pwm1 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
- status = "disabled";
};
/* Colibri PWM<D> */
&pwm2 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
- status = "disabled";
};
/* Colibri PWM<A> */
&pwm3 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
- status = "disabled";
};
/* Colibri PWM<C> */
&pwm4 {
+ #pwm-cells = <3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
- status = "disabled";
};
/* Optional S/PDIF out on SODIMM 137 */
@@ -356,6 +712,7 @@
};
&ssi1 {
+ fsl,mode = "i2s-slave";
status = "okay";
};
@@ -388,19 +745,25 @@
&usbotg {
pinctrl-names = "default";
disable-over-current;
- dr_mode = "peripheral";
+ dr_mode = "otg";
status = "disabled";
};
/* Colibri MMC */
&usdhc1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_mmc_cd>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_mmc_cd>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_mmc_cd>;
+ pinctrl-3 = <&pinctrl_usdhc1_sleep &pinctrl_mmc_cd_sleep>;
+ label = "MMC1";
+ bus-width = <4>;
cd-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* MMCD */
disable-wp;
- vqmmc-supply = <&reg_module_3v3>;
- bus-width = <4>;
+ enable-sdio-wakeup;
+ keep-power-in-suspend;
no-1-8-v;
+ vqmmc-supply = <&vgen3_reg>;
status = "disabled";
};
@@ -426,6 +789,73 @@
};
&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_gpio_1 &pinctrl_csi_gpio_2>;
+
+ imx6qdl-colibri {
+
+ /* Atmel MXT touchsceen + boards with built-in Capacitive Touch Connector */
+ pinctrl_atmel_conn: atmelconnectorgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0xb0b1 /* SODIMM_107 */
+ MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0xb0b1 /* SODIMM_106 */
+ >;
+ };
+
+ /* Atmel MXT touchsceen + Capacitive Touch Adapter */
+ /* NOTE: This pin group conflicts with pin groups
+ * pinctrl_pwm1/pinctrl_pwm4. Don't enable them
+ * simultaneously.
+ */
+ pinctrl_atmel_adap: atmeladaptergrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0xb0b1 /* SODIMM 28 */
+ MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0xb0b1 /* SODIMM 30 */
+ >;
+ };
+
+ /* CSI pins used as GPIO */
+ pinctrl_csi_gpio_1: csi_gpio-1 {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x1b0b0
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0
+ MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x1b0b0
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x1b0b0
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x130b0
+ MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x1b0b0
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x1b0b0
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b0
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x1b0b0
+ MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x1b0b0
+ MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0
+ >;
+ };
+ pinctrl_csi_gpio_2: csi_gpio-2 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpio_1: gpio-1 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x1b0b0
+ MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0
+ MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x1b0b0
+ MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x1b0b0
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x1b0b0
+ >;
+ };
+ pinctrl_gpio_2: gpio-2 {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0
+ >;
+ };
+
pinctrl_audmux: audmuxgrp {
fsl,pins = <
MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
@@ -495,10 +925,10 @@
>;
};
- pinctrl_hdmi_ddc: hdmiddcgrp {
+ pinctrl_i2c_ddc: i2c_ddc {
fsl,pins = <
- MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
- MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+ MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0 /* DDC bitbang */
+ MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x1b0b0 /* DDC bitbang */
>;
};
@@ -508,6 +938,12 @@
MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
>;
};
+ pinctrl_i2c2_recovery: i2c2-recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x4001b8b1
+ MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x4001b8b1
+ >;
+ };
pinctrl_i2c3: i2c3grp {
fsl,pins = <
@@ -584,7 +1020,7 @@
pinctrl_pwm1: pwm1grp {
fsl,pins = <
- MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1 /* SODIMM 28 */
>;
};
@@ -604,7 +1040,7 @@
pinctrl_pwm4: pwm4grp {
fsl,pins = <
- MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1
+ MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 /* SODIMM 30 */
>;
};
@@ -615,6 +1051,13 @@
>;
};
+ pinctrl_usbh_oc_1: usbh_oc-1 {
+ fsl,pins = <
+ /* USBH_OC */
+ MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x1b0b0
+ >;
+ };
+
pinctrl_spdif: spdifgrp {
fsl,pins = <
MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
@@ -681,6 +1124,13 @@
>;
};
+ pinctrl_usbc_id_1: usbc_id-1 {
+ fsl,pins = <
+ /* USBC_ID */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071
@@ -692,6 +1142,45 @@
>;
};
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170b1
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100b1
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170b1
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170b1
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170b1
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170b1
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f1
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f1
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f1
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f1
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f1
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f1
+ >;
+ };
+
+ pinctrl_mmc_cd_sleep: gpiommccdgrpslp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x0
+ >;
+ };
+
+ pinctrl_usdhc1_sleep: usdhc1grp_sleep {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x3000
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x3000
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x3000
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x3000
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x3000
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x3000
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -861,4 +1350,5 @@
MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0
>;
};
+ };
};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index aef9d63cb031..4ad486945be8 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -390,7 +390,7 @@
clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
<&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>,
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>,
- <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>,
+ <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_DUMMY>,
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
diff --git a/arch/arm/boot/dts/imx6ull-colibri-aster.dts b/arch/arm/boot/dts/imx6ull-colibri-aster.dts
new file mode 100644
index 000000000000..59652ef32bf2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-aster.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-nonwifi.dtsi"
+#include "imx6ull-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 256MB on Colibri Aster";
+ compatible = "toradex,colibri-imx6ull-aster",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-aster.dtsi b/arch/arm/boot/dts/imx6ull-colibri-aster.dtsi
new file mode 100644
index 000000000000..e7d6da210dc1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-aster.dtsi
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2018 Toradex AG
+ *
+ * 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 <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&ecspi1 {
+ status = "okay";
+
+ fsl,spi-num-chipselects = <2>;
+ /* Note: the gpio4 28 is muxed with pinctrl_gpio4 group, controlled
+ * by iomuxc.
+ */
+ cs-gpios = <
+ &gpio3 26 GPIO_ACTIVE_HIGH /* SODIMM_86 LCD_DATA21 */
+ &gpio4 28 GPIO_ACTIVE_HIGH /* SODIMM_65 CSI_DATA07 */
+ >;
+
+ spidev1: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <1>;
+ spi-max-frequency = <23000000>;
+ status = "okay";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/* PWM <A> */
+&pwm4 {
+ status = "okay";
+};
+
+/* PWM <B> */
+&pwm5 {
+ status = "okay";
+};
+
+/* PWM <C> */
+&pwm6 {
+ status = "okay";
+};
+
+/* PWM <D> */
+&pwm7 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ vmmc-supply = <&reg_3v3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-aster.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-aster.dts
new file mode 100644
index 000000000000..96b5c676f98a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-aster.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Aster";
+ compatible = "toradex,colibri-imx6ull-emmc-aster",
+ "toradex,colibri-imx6ull-emmc",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
new file mode 100644
index 000000000000..70104a6c5bac
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri-imx6ull-emmc-eval",
+ "toradex,colibri-imx6ull-emmc",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-iris-v2.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-iris-v2.dts
new file mode 100644
index 000000000000..b0c458722875
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-iris-v2.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 256MB on Colibri Iris V2";
+ compatible = "toradex,colibri-imx6ull-iris-v2",
+ "toradex,colibri-imx6ull-emmc",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-iris.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-iris.dts
new file mode 100644
index 000000000000..793951d8441a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-iris.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Iris";
+ compatible = "toradex,colibri-imx6ull-emmc-iris",
+ "toradex,colibri-imx6ull-emmc",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
new file mode 100644
index 000000000000..df055617e51f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+#include "imx6ull-colibri.dtsi"
+
+/ {
+ aliases {
+ mmc0 = &usdhc2; /* eMMC */
+ mmc1 = &usdhc1; /* MMC 4bit slot */
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>;
+ };
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_8",
+ "SODIMM_6",
+ "SODIMM_129",
+ "SODIMM_89",
+ "SODIMM_19",
+ "SODIMM_21",
+ "UNUSABLE_SODIMM_180",
+ "UNUSABLE_SODIMM_184",
+ "SODIMM_4",
+ "SODIMM_2",
+ "SODIMM_106",
+ "SODIMM_71",
+ "SODIMM_23",
+ "SODIMM_31",
+ "SODIMM_99",
+ "SODIMM_102",
+ "SODIMM_33",
+ "SODIMM_35",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_36",
+ "SODIMM_38",
+ "SODIMM_32",
+ "SODIMM_34",
+ "SODIMM_135",
+ "SODIMM_77",
+ "SODIMM_100",
+ "SODIMM_186",
+ "SODIMM_196",
+ "SODIMM_194";
+};
+
+&gpio2 {
+ gpio-line-names = "SODIMM_55",
+ "SODIMM_63",
+ "SODIMM_178",
+ "SODIMM_188",
+ "SODIMM_73",
+ "SODIMM_30",
+ "SODIMM_67",
+ "SODIMM_104",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_190",
+ "SODIMM_47",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_51",
+ "SODIMM_53";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_56",
+ "SODIMM_44",
+ "SODIMM_68",
+ "SODIMM_82",
+ "",
+ "SODIMM_76",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_57",
+ "SODIMM_61",
+ "SODIMM_29",
+ "SODIMM_37",
+ "SODIMM_88",
+ "SODIMM_86",
+ "SODIMM_92",
+ "SODIMM_90";
+};
+
+&gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_140",
+ "SODIMM_59",
+ "SODIMM_142",
+ "SODIMM_144",
+ "SODIMM_133",
+ "SODIMM_146",
+ "SODIMM_28",
+ "SODIMM_75",
+ "SODIMM_96",
+ "SODIMM_81",
+ "SODIMM_94",
+ "SODIMM_101",
+ "SODIMM_103",
+ "SODIMM_79",
+ "SODIMM_97",
+ "SODIMM_69",
+ "SODIMM_98",
+ "SODIMM_85",
+ "SODIMM_65";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_43",
+ "SODIMM_45",
+ "SODIMM_137",
+ "SODIMM_95",
+ "SODIMM_107",
+ "SODIMM_131",
+ "SODIMM_93",
+ "",
+ "SODIMM_138",
+ "",
+ "SODIMM_105",
+ "SODIMM_127";
+};
+
+&gpmi {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
+ &pinctrl_gpio4 &pinctrl_gpio6 &pinctrl_gpio7
+ &pinctrl_gpmi_gpio>;
+};
+
+&iomuxc_snvs {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio3>;
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2emmc>;
+ assigned-clocks = <&clks IMX6UL_CLK_USDHC2_SEL>, <&clks IMX6UL_CLK_USDHC2>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+ assigned-clock-rates = <0>, <198000000>;
+ bus-width = <8>;
+ keep-power-in-suspend;
+ no-1-8-v;
+ non-removable;
+ vmmc-supply = <&reg_module_3v3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts
index 08669a18349e..4016fbb53bad 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex
*/
/dts-v1/;
@@ -10,5 +10,7 @@
/ {
model = "Toradex Colibri iMX6ULL 256MB on Colibri Evaluation Board V3";
- compatible = "toradex,colibri-imx6ull-eval", "fsl,imx6ull";
+ compatible = "toradex,colibri-imx6ull-eval",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
index b6147c76d159..821523a12423 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
@@ -3,11 +3,26 @@
* Copyright 2017 Toradex AG
*/
+#include <dt-bindings/pwm/pwm.h>
+
/ {
chosen {
stdout-path = "serial0:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_gpiokeys>;
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ wakeup-source;
+ };
+ };
+
/* fixed crystal dedicated to mcp2515 */
clk16m: clk16m {
compatible = "fixed-clock";
@@ -15,16 +30,12 @@
clock-frequency = <16000000>;
};
- panel: panel {
- compatible = "edt,et057090dhu";
- backlight = <&bl>;
- power-supply = <&reg_3v3>;
-
- port {
- panel_in: endpoint {
- remote-endpoint = <&lcdif_out>;
- };
- };
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_usbc_det>;
};
reg_3v3: regulator-3v3 {
@@ -57,11 +68,7 @@
status = "okay";
};
-&bl {
- brightness-levels = <0 4 8 16 32 64 128 255>;
- default-brightness-level = <6>;
- power-supply = <&reg_3v3>;
- pwms = <&pwm4 0 5000000 1>;
+&pxp {
status = "okay";
};
@@ -81,6 +88,25 @@
xceiver-supply = <&reg_5v0>;
status = "okay";
};
+
+ /* To keep the CAN controller enabled by default,
+ * disable conflicting spidev.
+ */
+ spidev0: spidev@0 {
+ status = "disabled";
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "disabled";
};
&i2c1 {
@@ -93,14 +119,13 @@
};
};
-&lcdif {
- status = "okay";
- port {
- lcdif_out: endpoint {
- remote-endpoint = <&panel_in>;
- };
- };
+&atmel_mxt_ts {
+ pinctrl-0 = <&pinctrl_atmel_adap>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <16 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28, INT */
+ reset-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* SODIMM 30, RST */
+ status = "disabled";
};
/* PWM <A> */
@@ -108,6 +133,11 @@
status = "okay";
};
+/*
+ * the PCAPs use SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm5,
+ * pwm6. so if you enable one of the PCAP controllers disable the pwms
+ */
+
/* PWM <B> */
&pwm5 {
status = "okay";
@@ -136,6 +166,8 @@
};
&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
status = "okay";
};
@@ -145,20 +177,17 @@
};
&usdhc1 {
- pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
- pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_cd>;
- pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_snvs_usdhc1_cd>;
- pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_snvs_usdhc1_cd>;
- pinctrl-3 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_sleep_cd>;
- cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
- disable-wp;
- wakeup-source;
- keep-power-in-suspend;
vmmc-supply = <&reg_3v3>;
- vqmmc-supply = <&reg_sd1_vmmc>;
- sd-uhs-sdr12;
- sd-uhs-sdr25;
- sd-uhs-sdr50;
- sd-uhs-sdr104;
status = "okay";
};
+
+&iomuxc {
+ imx6ull-colibri {
+ pinctrl_gpiotouch: touchgpios {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x74
+ MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0x14
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dts b/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dts
new file mode 100644
index 000000000000..1906b7dffef7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-nonwifi.dtsi"
+#include "imx6ull-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 256MB on Colibri Iris V2";
+ compatible = "toradex,colibri-imx6ull-iris-v2",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
+
+&gpio1 {
+ lvds_tx_on {
+ gpio-hog;
+ gpios = <14 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dtsi b/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dtsi
new file mode 100644
index 000000000000..91702bb03dd1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-iris-v2.dtsi
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2019 Toradex
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_usbc_det>;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/* PWM <A> */
+&pwm4 {
+ status = "okay";
+};
+
+/* PWM <B> */
+&pwm5 {
+ status = "okay";
+};
+
+/* PWM <C> */
+&pwm6 {
+ status = "okay";
+};
+
+/* PWM <D> */
+&pwm7 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&uart1 {
+ status = "okay";
+};
+
+/* Colibri UART_B */
+&uart2 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&uart5 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ cap-power-off-card;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ /delete-property/ keep-power-in-suspend;
+ /delete-property/ no-1-8-v;
+ status = "okay";
+};
+
+&gpio1 {
+ uart25_tx_on {
+ gpio-hog;
+ gpios = <15 0>;
+ output-high;
+ };
+};
+
+&gpio2 {
+ uart1_tx_on {
+ gpio-hog;
+ gpios = <7 0>;
+ output-high;
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx6ull-colibri-iris.dts b/arch/arm/boot/dts/imx6ull-colibri-iris.dts
new file mode 100644
index 000000000000..0eb38ecc8f21
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-iris.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-nonwifi.dtsi"
+#include "imx6ull-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 256MB on Colibri Iris";
+ compatible = "toradex,colibri-imx6ull-iris",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-iris.dtsi b/arch/arm/boot/dts/imx6ull-colibri-iris.dtsi
new file mode 100644
index 000000000000..4745a52924c4
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-iris.dtsi
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2019 Toradex
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_snvs_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&pxp {
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/* Atmel TS adapter */
+&atmel_mxt_ts {
+ pinctrl-0 = <&pinctrl_atmel_adap>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <16 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28, INT */
+ reset-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* SODIMM 30, RST */
+ status = "disabled";
+};
+
+/* PWM <A> */
+&pwm4 {
+ status = "okay";
+};
+
+/*
+ * the PCAPs use SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm5,
+ * pwm6. so if you enable one of the PCAP controllers disable the pwms
+ */
+
+/* PWM <B> */
+&pwm5 {
+ status = "okay";
+};
+
+/* PWM <C> */
+&pwm6 {
+ status = "okay";
+};
+
+/* PWM <D> */
+&pwm7 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&uart1 {
+ status = "okay";
+};
+
+/* Colibri UART_B */
+&uart2 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&uart5 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ vmmc-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+&gpio1 {
+ /*
+ * uart25_tx_on turns the UART transceiver on. If one wants to turn the
+ * transceiver off, that property has to be deleted and the gpio handled
+ * in userspace.
+ * The same applies to uart1_tx_on.
+ */
+ uart25_tx_on {
+ gpio-hog;
+ gpios = <15 0>;
+ output-high;
+ };
+};
+
+&gpio2 {
+ uart1_tx_on {
+ gpio-hog;
+ gpios = <7 0>;
+ output-high;
+ };
+};
+
diff --git a/arch/arm/boot/dts/imx6ull-colibri-lcdif.dtsi b/arch/arm/boot/dts/imx6ull-colibri-lcdif.dtsi
new file mode 100644
index 000000000000..6c2ea9ad8c37
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-lcdif.dtsi
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+#include "imx6ull.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bl_on>;
+ enable-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ pwms = <&pwm4 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ imx6ull-colibri {
+ pinctrl_lcdif_dat: lcdif-dat-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x00079 /* SODIMM 76 */
+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x00079 /* SODIMM 70 */
+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x00079 /* SODIMM 60 */
+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x00079 /* SODIMM 58 */
+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x00079 /* SODIMM 78 */
+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x00079 /* SODIMM 72 */
+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x00079 /* SODIMM 80 */
+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x00079 /* SODIMM 46 */
+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x00079 /* SODIMM 62 */
+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x00079 /* SODIMM 48 */
+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x00079 /* SODIMM 74 */
+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x00079 /* SODIMM 50 */
+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x00079 /* SODIMM 52 */
+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x00079 /* SODIMM 54 */
+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x00079 /* SODIMM 66 */
+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x00079 /* SODIMM 64 */
+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x00079 /* SODIMM 57 */
+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x00079 /* SODIMM 61 */
+ >;
+ };
+
+ pinctrl_lcdif_ctrl: lcdif-ctrl-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x00079 /* SODIMM 56 */
+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x00079 /* SODIMM 44 */
+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x00079 /* SODIMM 68 */
+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x00079 /* SODIMM 82 */
+ >;
+ };
+
+ pinctrl_pwm4: pwm4-grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x00079 /* SODIMM 59 */
+ >;
+ };
+ }; /* imx6ull-colibri { */
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif_dat
+ &pinctrl_lcdif_ctrl>;
+
+ display = <&display0>;
+ status = "disabled";
+
+ display0: lcd-display {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing_vga>;
+
+ /* Standard VGA timing */
+ timing_vga: 640x480 {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ hsync-len = <96>;
+ vsync-len = <2>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ /* WVGA Timing, e.g. EDT ET070080DH6 */
+ timing_wvga: 800x480 {
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <216>;
+ hfront-porch = <40>;
+ vback-porch = <35>;
+ vfront-porch = <10>;
+ hsync-len = <128>;
+ vsync-len = <2>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ /* WVGA Timing, TouchRevolution Fusion 7" */
+ timing_wvga2: 800x480pixclkact {
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <216>;
+ hfront-porch = <40>;
+ vback-porch = <35>;
+ vfront-porch = <10>;
+ hsync-len = <128>;
+ vsync-len = <2>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <1>;
+ };
+ /* Standard SVGA timing */
+ timing_svga: 800x600 {
+ clock-frequency = <40000000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <88>;
+ hfront-porch = <40>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ hsync-len = <128>;
+ vsync-len = <4>;
+ de-active = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pixelclk-active = <0>;
+ };
+ /* TouchRevolution Fusion 10"/CLAA101NC05 10.1 inch */
+ timing_wsvga: 1024x600 {
+ clock-frequency = <48000000>;
+ hactive = <1024>;
+ vactive = <600>;
+ hback-porch = <104>;
+ hfront-porch = <43>;
+ vback-porch = <24>;
+ vfront-porch = <20>;
+ hsync-len = <5>;
+ vsync-len = <5>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ /* Standard XGA timing */
+ timing_xga: 1024x768 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <160>;
+ hfront-porch = <24>;
+ vback-porch = <29>;
+ vfront-porch = <3>;
+ hsync-len = <136>;
+ vsync-len = <6>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ /* WXGA Timing, LT170410 display 10" */
+ timing_wxga: 1280x800 {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
index fb213bec4654..a324b4fba8ca 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex
*/
#include "imx6ull-colibri.dtsi"
@@ -12,13 +12,174 @@
};
};
+&ad7879_ts {
+ status = "okay";
+};
+
+&backlight {
+ status = "okay";
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_8",
+ "SODIMM_6",
+ "SODIMM_129",
+ "SODIMM_89",
+ "SODIMM_19",
+ "SODIMM_21",
+ "UNUSABLE_SODIMM_180",
+ "UNUSABLE_SODIMM_184",
+ "SODIMM_4",
+ "SODIMM_2",
+ "SODIMM_106",
+ "SODIMM_71",
+ "SODIMM_23",
+ "SODIMM_31",
+ "SODIMM_99",
+ "SODIMM_102",
+ "SODIMM_33",
+ "SODIMM_35",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_36",
+ "SODIMM_38",
+ "SODIMM_32",
+ "SODIMM_34",
+ "SODIMM_135",
+ "SODIMM_77",
+ "SODIMM_100",
+ "SODIMM_186",
+ "SODIMM_196",
+ "SODIMM_194";
+};
+
+&gpio2 {
+ gpio-line-names = "SODIMM_55",
+ "SODIMM_63",
+ "SODIMM_178",
+ "SODIMM_188",
+ "SODIMM_73",
+ "SODIMM_30",
+ "SODIMM_67",
+ "SODIMM_104",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_190",
+ "SODIMM_47",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_51",
+ "SODIMM_53";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_56",
+ "SODIMM_44",
+ "SODIMM_68",
+ "SODIMM_82",
+ "",
+ "SODIMM_76",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_57",
+ "SODIMM_61",
+ "SODIMM_29",
+ "SODIMM_37",
+ "SODIMM_88",
+ "SODIMM_86",
+ "SODIMM_92",
+ "SODIMM_90";
+};
+
+&gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_59",
+ "",
+ "",
+ "SODIMM_133",
+ "",
+ "SODIMM_28",
+ "SODIMM_75",
+ "SODIMM_96",
+ "SODIMM_81",
+ "SODIMM_94",
+ "SODIMM_101",
+ "SODIMM_103",
+ "SODIMM_79",
+ "SODIMM_97",
+ "SODIMM_69",
+ "SODIMM_98",
+ "SODIMM_85",
+ "SODIMM_65";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_43",
+ "SODIMM_45",
+ "SODIMM_137",
+ "SODIMM_95",
+ "SODIMM_107",
+ "SODIMM_131",
+ "SODIMM_93",
+ "",
+ "SODIMM_138",
+ "",
+ "SODIMM_105",
+ "SODIMM_127";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
- &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6>;
+ &pinctrl_gpio4 &pinctrl_gpio6 &pinctrl_gpio7>;
};
&iomuxc_snvs {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio2 &pinctrl_snvs_gpio3>;
+ pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio3>;
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi-aster.dts b/arch/arm/boot/dts/imx6ull-colibri-wifi-aster.dts
new file mode 100644
index 000000000000..f1b4942564f5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi-aster.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-wifi.dtsi"
+#include "imx6ull-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 512MB on Colibri Aster";
+ compatible = "toradex,colibri-imx6ull-wifi-aster",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts
index df72ce1ae2cb..6c5f44ec6d51 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi-iris-v2.dts b/arch/arm/boot/dts/imx6ull-colibri-wifi-iris-v2.dts
new file mode 100644
index 000000000000..95e28f5aac6d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi-iris-v2.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-wifi.dtsi"
+#include "imx6ull-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 512MB on Colibri Iris V2";
+ compatible = "toradex,colibri-imx6ull-wifi-iris-v2",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
+
+&gpio1 {
+ lvds_tx_on {
+ gpio-hog;
+ gpios = <14 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi-iris.dts b/arch/arm/boot/dts/imx6ull-colibri-wifi-iris.dts
new file mode 100644
index 000000000000..15d893088616
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi-iris.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-wifi.dtsi"
+#include "imx6ull-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6ULL 512MB on Colibri Iris";
+ compatible = "toradex,colibri-imx6ull-wifi-iris",
+ "toradex,colibri-imx6ull",
+ "fsl,imx6ull";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
index 621396884c31..237757d7df8b 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex
*/
#include "imx6ull-colibri.dtsi"
@@ -19,20 +19,176 @@
};
};
-&cpu0 {
- clock-frequency = <792000000>;
+&ad7879_ts {
+ status = "okay";
+};
+
+&backlight {
+ status = "okay";
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_8",
+ "SODIMM_6",
+ "SODIMM_129",
+ "",
+ "SODIMM_19",
+ "SODIMM_21",
+ "UNUSABLE_SODIMM_180",
+ "UNUSABLE_SODIMM_184",
+ "SODIMM_4",
+ "SODIMM_2",
+ "SODIMM_106",
+ "SODIMM_71",
+ "SODIMM_23",
+ "SODIMM_31",
+ "SODIMM_99",
+ "SODIMM_102",
+ "SODIMM_33",
+ "SODIMM_35",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_36",
+ "SODIMM_38",
+ "SODIMM_32",
+ "SODIMM_34",
+ "SODIMM_135",
+ "SODIMM_77",
+ "SODIMM_100",
+ "SODIMM_186",
+ "SODIMM_196",
+ "SODIMM_194";
+};
+
+&gpio2 {
+ gpio-line-names = "SODIMM_55",
+ "SODIMM_63",
+ "SODIMM_178",
+ "SODIMM_188",
+ "SODIMM_73",
+ "SODIMM_30",
+ "SODIMM_67",
+ "SODIMM_104",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_190",
+ "SODIMM_47",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_51",
+ "SODIMM_53";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_56",
+ "SODIMM_44",
+ "SODIMM_68",
+ "SODIMM_82",
+ "",
+ "SODIMM_76",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_57",
+ "SODIMM_61",
+ "SODIMM_29",
+ "SODIMM_37",
+ "SODIMM_88",
+ "SODIMM_86",
+ "SODIMM_92",
+ "SODIMM_90";
+};
+
+&gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_59",
+ "",
+ "",
+ "SODIMM_133",
+ "",
+ "SODIMM_28",
+ "SODIMM_75",
+ "SODIMM_96",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_69",
+ "SODIMM_98",
+ "SODIMM_85",
+ "SODIMM_65";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_43",
+ "SODIMM_45",
+ "SODIMM_137",
+ "SODIMM_95",
+ "SODIMM_107",
+ "SODIMM_131",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_105";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
- &pinctrl_gpio4 &pinctrl_gpio5>;
+ &pinctrl_gpio4 &pinctrl_gpio7>;
};
&iomuxc_snvs {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio2>;
+ pinctrl-0 = <&pinctrl_snvs_gpio1>;
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
};
&usdhc2 {
@@ -49,5 +205,6 @@
non-removable;
vmmc-supply = <&reg_module_3v3>;
wakeup-source;
+ wifi-host;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
index c83323b9ea53..9e83142ba073 100644
--- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex AG
*/
#include "imx6ull.dtsi"
+#include "imx6ull-colibri-lcdif.dtsi"
+#include <dt-bindings/pwm/pwm.h>
/ {
aliases {
@@ -11,12 +13,27 @@
ethernet1 = &fec1;
};
- bl: backlight {
- compatible = "pwm-backlight";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_bl_on>;
- enable-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
- status = "disabled";
+ memory {
+ reg = <0x80000000 0x10000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x08000000>;
+ linux,cma-default;
+ };
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", \
+ "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
};
reg_module_3v3: regulator-module-3v3 {
@@ -35,7 +52,7 @@
regulator-max-microvolt = <3300000>;
};
- reg_sd1_vmmc: regulator-sd1-vmmc {
+ reg_sd1_vqmmc: regulator-sd1-vqmmc {
compatible = "regulator-gpio";
gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
@@ -47,25 +64,58 @@
states = <1800000 0x1 3300000 0x0>;
vin-supply = <&reg_module_3v3>;
};
+
+ reg_soc_in: regulator-soc-in {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <1275000>;
+ regulator-max-microvolt = <1275000>;
+ regulator-name = "soc_in";
+ regulator-type = "voltage";
+ vin-supply = <&reg_module_3v3>;
+ };
+
+ reg_eth_phy: regulator-eth-phy {
+ compatible = "regulator-fixed-clock";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "eth_phy";
+ regulator-type = "voltage";
+ vin-supply = <&reg_module_3v3>;
+ clocks = <&clks IMX6UL_CLK_ENET2_REF_125M>;
+ startup-delay-us = <150000>;
+ };
};
&adc1 {
num-channels = <10>;
vref-supply = <&reg_module_3v3_avdd>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc1>;
};
+
/* Colibri SPI */
&ecspi1 {
cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
+ status = "okay";
+ };
};
&fec2 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_enet2>;
+ pinctrl-1 = <&pinctrl_enet2_sleep>;
phy-mode = "rmii";
phy-handle = <&ethphy1>;
+ phy-supply = <&reg_eth_phy>;
status = "okay";
mdio {
@@ -80,6 +130,14 @@
};
};
+&gpc {
+ fsl,cpu_pupscr_sw2iso = <0x1>;
+ fsl,cpu_pupscr_sw = <0x0>;
+ fsl,cpu_pdnscr_iso2sw = <0x1>;
+ fsl,cpu_pdnscr_iso = <0x1>;
+ fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
+};
+
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
@@ -96,17 +154,43 @@
pinctrl-1 = <&pinctrl_i2c1_gpio>;
sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_conn>;
+ reg = <0x4a>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* SODIMM_107, INT */
+ reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; /* SODIMM_106, RST */
+ status = "disabled";
+ };
+
+ /* TouchRevolution Fusion 7 and 10 multi-touch controller */
+ fusion_f0710a: touchscreen@10 {
+ compatible = "touchrevolution,fusion-f0710a";
+ reg = <0x10>;
+ pinctrl-0 = <&pinctrl_atmel_adap>;
+ pinctrl-names = "default";
+ gpios = <&gpio4 16 GPIO_ACTIVE_HIGH /* SODIMM_28, INT */
+ &gpio2 5 GPIO_ACTIVE_LOW>; /* SODIMM_30, RST */
+ status = "disabled";
+ };
};
&i2c2 {
+ /* use low frequency to compensate for the high pull up values */
+ clock-frequency = <40000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
pinctrl-1 = <&pinctrl_i2c2_gpio>;
sda-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
scl-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- status = "okay";
+ status = "disabled";
- ad7879@2c {
+ ad7879_ts: touchscreen@2c {
compatible = "adi,ad7879-1";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_snvs_ad7879_int>;
@@ -120,21 +204,10 @@
adi,median-filter-size = /bits/ 8 <2>;
adi,averaging = /bits/ 8 <1>;
adi,conversion-interval = /bits/ 8 <255>;
+ status = "disabled";
};
};
-&lcdif {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_lcdif_dat
- &pinctrl_lcdif_ctrl>;
-};
-
-&pwm4 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm4>;
- #pwm-cells = <3>;
-};
-
&pwm5 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm5>;
@@ -153,6 +226,10 @@
#pwm-cells = <3>;
};
+&pxp {
+ status = "okay";
+};
+
&sdma {
status = "okay";
};
@@ -164,14 +241,14 @@
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1>;
- uart-has-rtscts;
+ fsl,uart-has-rtscts;
fsl,dte-mode;
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
- uart-has-rtscts;
+ fsl,uart-has-rtscts;
fsl,dte-mode;
};
@@ -193,359 +270,413 @@
};
&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_cd>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_snvs_usdhc1_cd>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_snvs_usdhc1_cd>;
+ pinctrl-3 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_sleep_cd>;
assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>;
assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
assigned-clock-rates = <0>, <198000000>;
+ bus-width = <4>;
+ cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ keep-power-in-suspend;
+ no-1-8-v;
+ vqmmc-supply = <&reg_sd1_vqmmc>;
+ wakeup-source;
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
};
&iomuxc {
- pinctrl_can_int: canint-grp {
- fsl,pins = <
- MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0X14 /* SODIMM 73 */
- >;
- };
+ imx6ull-colibri {
+ pinctrl_adc1: adc1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0x3000 /* SODIMM 8 */
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x3000 /* SODIMM 6 */
+ MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0x3000 /* SODIMM 4 */
+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x3000 /* SODIMM 2 */
+ >;
+ };
- pinctrl_enet2: enet2-grp {
- fsl,pins = <
- MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
- MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
- MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
- MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
- MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
- MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
- MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
- MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
- MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
- MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
- >;
- };
+ pinctrl_atmel_adap: atmel_adap_group {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DQS__GPIO4_IO16 0xb0a0 /* SODIMM 28 */
+ MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0xb0a0 /* SODIMM 30 */
+ >;
+ };
- pinctrl_ecspi1_cs: ecspi1-cs-grp {
- fsl,pins = <
- MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x000a0
- >;
- };
+ pinctrl_atmel_conn: atmel_conn_group {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0xb0a0 /* SODIMM 106 */
+ MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0xb0a0 /* SODIMM 107 */
+ >;
+ };
- pinctrl_ecspi1: ecspi1-grp {
- fsl,pins = <
- MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x000a0
- MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x000a0
- MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x100a0
- >;
- };
+ pinctrl_can_int: canint-grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x13010 /* SODIMM 73 */
+ >;
+ };
- pinctrl_flexcan2: flexcan2-grp {
- fsl,pins = <
- MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x1b020
- MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x1b020
- >;
- };
+ pinctrl_enet2: enet2-grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
+ >;
+ };
- pinctrl_gpio_bl_on: gpio-bl-on-grp {
- fsl,pins = <
- MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x000a0
- >;
- };
+ pinctrl_enet2_sleep: enet2sleepgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO06__GPIO1_IO06 0x0
+ MX6UL_PAD_GPIO1_IO07__GPIO1_IO07 0x0
+ MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x0
+ MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x0
+ MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x0
+ MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x0
+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
+ MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x0
+ MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12 0x0
+ MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x0
+ >;
+ };
- pinctrl_gpio1: gpio1-grp {
- fsl,pins = <
- MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x74 /* SODIMM 55 */
- MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x74 /* SODIMM 63 */
- MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0X14 /* SODIMM 77 */
- MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x14 /* SODIMM 99 */
- MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x14 /* SODIMM 133 */
- MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x14 /* SODIMM 135 */
- MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x14 /* SODIMM 100 */
- MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x14 /* SODIMM 102 */
- MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x14 /* SODIMM 104 */
- MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x14 /* SODIMM 186 */
- >;
- };
+ pinctrl_ecspi1_cs: ecspi1-cs-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x70a0 /* SODIMM 86 */
+ >;
+ };
- pinctrl_gpio2: gpio2-grp { /* Camera */
- fsl,pins = <
- MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x74 /* SODIMM 69 */
- MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x14 /* SODIMM 75 */
- MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x14 /* SODIMM 85 */
- MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x14 /* SODIMM 96 */
- MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x14 /* SODIMM 98 */
- >;
- };
+ pinctrl_ecspi1: ecspi1-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x000a0 /* SODIMM 88 */
+ MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x000a0 /* SODIMM 92 */
+ MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x100a0 /* SODIMM 90 */
+ >;
+ };
- pinctrl_gpio3: gpio3-grp { /* CAN2 */
- fsl,pins = <
- MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x14 /* SODIMM 178 */
- MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x14 /* SODIMM 188 */
- >;
- };
+ pinctrl_flexcan1: flexcan1-grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x1b020
+ MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x1b020
+ >;
+ };
- pinctrl_gpio4: gpio4-grp {
- fsl,pins = <
- MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x74 /* SODIMM 65 */
- >;
- };
+ pinctrl_flexcan2: flexcan2-grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x1b020
+ MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x1b020
+ >;
+ };
- pinctrl_gpio5: gpio5-grp { /* ATMEL MXT TOUCH */
- fsl,pins = <
- MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x74 /* SODIMM 106 */
- >;
- };
+ pinctrl_gpio_bl_on: gpio-bl-on-grp {
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x30a0 /* SODIMM 71 */
+ >;
+ };
- pinctrl_gpio6: gpio6-grp { /* Wifi pins */
- fsl,pins = <
- MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x14 /* SODIMM 89 */
- MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x14 /* SODIMM 79 */
- MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x14 /* SODIMM 81 */
- MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x14 /* SODIMM 97 */
- MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x14 /* SODIMM 101 */
- MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x14 /* SODIMM 103 */
- MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x14 /* SODIMM 94 */
- >;
- };
+ pinctrl_gpio1: gpio1-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x10b0 /* SODIMM 77 */
+ MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x70a0 /* SODIMM 99 */
+ MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x10b0 /* SODIMM 133 */
+ MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x10b0 /* SODIMM 135 */
+ MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x10b0 /* SODIMM 100 */
+ MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x70a0 /* SODIMM 102 */
+ MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x10b0 /* SODIMM 104 */
+ MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x10b0 /* SODIMM 186 */
+ >;
+ };
- pinctrl_gpmi_nand: gpmi-nand-grp {
- fsl,pins = <
- MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x100a9
- MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x100a9
- MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x100a9
- MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x100a9
- MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x100a9
- MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x100a9
- MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x100a9
- MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x100a9
- MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x100a9
- MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x100a9
- MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x100a9
- MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x100a9
- MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x100a9
- MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x100a9
- >;
- };
+ pinctrl_gpio2: gpio2-grp { /* Camera */
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x10b0 /* SODIMM 69 */
+ MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x10b0 /* SODIMM 75 */
+ MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x10b0 /* SODIMM 85 */
+ MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x10b0 /* SODIMM 96 */
+ MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x10b0 /* SODIMM 98 */
+ >;
+ };
- pinctrl_i2c1: i2c1-grp {
- fsl,pins = <
- MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
- MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
- >;
- };
+ pinctrl_gpio3: gpio3-grp { /* CAN2 */
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x10b0 /* SODIMM 178 */
+ MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x10b0 /* SODIMM 188 */
+ >;
+ };
- pinctrl_i2c1_gpio: i2c1-gpio-grp {
- fsl,pins = <
- MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0
- MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0
- >;
- };
+ pinctrl_gpio4: gpio4-grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x10b0 /* SODIMM 65 */
+ >;
+ };
- pinctrl_i2c2: i2c2-grp {
- fsl,pins = <
- MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
- MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
- >;
- };
+ pinctrl_gpio6: gpio6-grp { /* Wifi pins */
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10b0 /* SODIMM 89 */
+ MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x10b0 /* SODIMM 79 */
+ MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x10b0 /* SODIMM 81 */
+ MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x10b0 /* SODIMM 97 */
+ MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x10b0 /* SODIMM 101 */
+ MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x10b0 /* SODIMM 103 */
+ MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x10b0 /* SODIMM 94 */
+ >;
+ };
- pinctrl_i2c2_gpio: i2c2-gpio-grp {
- fsl,pins = <
- MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x4001b8b0
- MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x4001b8b0
- >;
- };
+ pinctrl_gpio7: gpio7-grp { /* CAN1 */
+ fsl,pins = <
+ MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0xb0b0 /* SODIMM 55 */
+ MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0xb0b0 /* SODIMM 63 */
+ >;
+ };
- pinctrl_lcdif_dat: lcdif-dat-grp {
- fsl,pins = <
- MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x00079
- MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x00079
- MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x00079
- MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x00079
- MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x00079
- MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x00079
- MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x00079
- MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x00079
- MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x00079
- MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x00079
- MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x00079
- MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x00079
- MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x00079
- MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x00079
- MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x00079
- MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x00079
- MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x00079
- MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x00079
- >;
- };
+ /*
+ * With an eMMC instead of a raw NAND device the following pins
+ * are available at SODIMM pins
+ */
+ pinctrl_gpmi_gpio: gpmi-gpio-grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x10b0 /* SODIMM 140 */
+ MX6UL_PAD_NAND_CE0_B__GPIO4_IO13 0x10b0 /* SODIMM 144 */
+ MX6UL_PAD_NAND_CLE__GPIO4_IO15 0x10b0 /* SODIMM 146 */
+ MX6UL_PAD_NAND_READY_B__GPIO4_IO12 0x10b0 /* SODIMM 142 */
+ >;
+ };
- pinctrl_lcdif_ctrl: lcdif-ctrl-grp {
- fsl,pins = <
- MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x00079
- MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x00079
- MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x00079
- MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x00079
- >;
- };
+ pinctrl_gpmi_nand: gpmi-nand-grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x100a9
+ MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x100a9
+ MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x100a9
+ MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x100a9
+ MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x100a9
+ MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x100a9
+ MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x100a9
+ MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x100a9
+ MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x100a9
+ MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x100a9
+ MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x100a9
+ MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x100a9
+ MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x100a9
+ MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x100a9
+ >;
+ };
- pinctrl_pwm4: pwm4-grp {
- fsl,pins = <
- MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x00079
- >;
- };
+ pinctrl_i2c1: i2c1-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 /* SODIMM 196 */
+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 /* SODIMM 194 */
+ >;
+ };
- pinctrl_pwm5: pwm5-grp {
- fsl,pins = <
- MX6UL_PAD_NAND_DQS__PWM5_OUT 0x00079
- >;
- };
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0 /* SODIMM 196 */
+ MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0 /* SODIMM 194 */
+ >;
+ };
- pinctrl_pwm6: pwm6-grp {
- fsl,pins = <
- MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079
- >;
- };
+ pinctrl_i2c2: i2c2-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001f8b0
+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001f8b0
+ >;
+ };
- pinctrl_pwm7: pwm7-grp {
- fsl,pins = <
- MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00079
- >;
- };
+ pinctrl_i2c2_gpio: i2c2-gpio-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x4001f8b0
+ MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x4001f8b0
+ >;
+ };
- pinctrl_uart1: uart1-grp {
- fsl,pins = <
- MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x1b0b1
- MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x1b0b1
- MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x1b0b1
- MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x1b0b1
- >;
- };
+ pinctrl_pwm5: pwm5-grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_DQS__PWM5_OUT 0x00079 /* SODIMM 28 */
+ >;
+ };
- pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
- fsl,pins = <
- MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x1b0b1 /* DCD */
- MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x1b0b1 /* DSR */
- MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x1b0b1 /* DTR */
- MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x1b0b1 /* RI */
- >;
- };
+ pinctrl_pwm6: pwm6-grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079 /* SODIMM 30 */
+ >;
+ };
- pinctrl_uart2: uart2-grp {
- fsl,pins = <
- MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
- MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1
- MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1
- MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1
- >;
- };
- pinctrl_uart5: uart5-grp {
- fsl,pins = <
- MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x1b0b1
- MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x1b0b1
- >;
- };
+ pinctrl_pwm7: pwm7-grp {
+ fsl,pins = <
+ MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00079 /* SODIMM 67 */
+ >;
+ };
- pinctrl_usbh_reg: gpio-usbh-reg {
- fsl,pins = <
- MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x1b0b1 /* SODIMM 129 USBH PEN */
- >;
- };
+ pinctrl_uart1: uart1-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x1b0b1 /* SODIMM 33 */
+ MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x1b0b1 /* SODIMM 35 */
+ MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x1b0b1 /* SODIMM 27 */
+ MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x1b0b1 /* SODIMM 25 */
+ >;
+ };
- pinctrl_usdhc1: usdhc1-grp {
- fsl,pins = <
- MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x17059
- MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x10059
- MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
- MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
- MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
- MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
- >;
- };
+ pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
+ fsl,pins = <
+ MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x70a0 /* SODIMM 31 */
+ MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x10b0 /* SODIMM 29 */
+ MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x90b1 /* SODIMM 23 */
+ MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x10b0 /* SODIMM 37 */
+ >;
+ };
- pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp {
- fsl,pins = <
- MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170b9
- MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100b9
- MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
- MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
- MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
- MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
- >;
- };
+ pinctrl_uart2: uart2-grp {
+ fsl,pins = <
+ MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1 /* SODIMM 36 */
+ MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1 /* SODIMM 38 */
+ MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1 /* SODIMM 32 */
+ MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1 /* SODIMM 34 */
+ >;
+ };
+ pinctrl_uart5: uart5-grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x1b0b1 /* SODIMM 19 */
+ MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x1b0b1 /* SODIMM 21 */
+ >;
+ };
- pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp {
- fsl,pins = <
- MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170f9
- MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100f9
- MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
- MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
- MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
- MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
- >;
- };
+ pinctrl_usbh_reg: gpio-usbh-reg {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x10b0 /* SODIMM 129 */
+ >;
+ };
- pinctrl_usdhc2: usdhc2-grp {
- fsl,pins = <
- MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059
- MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059
- MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059
- MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059
- MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059
- MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x17059
-
- MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT 0x14
- >;
- };
+ pinctrl_usdhc1: usdhc1-grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059 /* SODIMM 47 */
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059 /* SODIMM 190 */
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059 /* SODIMM 192 */
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059 /* SODIMM 49 */
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059 /* SODIMM 51 */
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059 /* SODIMM 53 */
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp {
+ fsl,pins = <
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2-grp {
+ fsl,pins = <
+ MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17069
+ MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17069
+ MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17069
+ MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17069
+ MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17069
+ MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x10069
+
+ MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT 0x10
+ >;
+ };
+
+ pinctrl_usdhc2emmc: usdhc2emmcgrp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x17059
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_wdog: wdog-grp {
+ fsl,pins = <
+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
+ >;
+ };
+ }; /* imx6ull { */
};
&iomuxc_snvs {
pinctrl_snvs_gpio1: snvs-gpio1-grp {
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x14 /* SODIMM 93 */
- MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x14 /* SODIMM 95 */
- MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x74 /* SODIMM 105 */
- MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x14 /* SODIMM 131 USBH OC */
- MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x74 /* SODIMM 138 */
- >;
- };
-
- pinctrl_snvs_gpio2: snvs-gpio2-grp { /* ATMEL MXT TOUCH */
- fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x74 /* SODIMM 107 */
+ MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x110a0 /* SODIMM 93 */
+ MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x110a0 /* SODIMM 95 */
+ MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x1b0a0 /* SODIMM 105 */
+ MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x0b0a0 /* SODIMM 131 */
+ MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x110a0 /* SODIMM 138 */
>;
};
pinctrl_snvs_gpio3: snvs-gpio3-grp { /* Wifi pins */
fsl,pins = <
- MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14 /* SODIMM 127 */
+ MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x130a0 /* SODIMM 127 */
>;
};
pinctrl_snvs_ad7879_int: snvs-ad7879-int-grp { /* TOUCH Interrupt */
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x1b0b0
+ MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x1b0a0
>;
};
pinctrl_snvs_reg_sd: snvs-reg-sd-grp {
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x4001b8b0
+ MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x130a0
>;
};
pinctrl_snvs_usbc_det: snvs-usbc-det-grp {
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x1b0b0
+ MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x130a0 /* SODIMM 137 */
>;
};
pinctrl_snvs_gpiokeys: snvs-gpiokeys-grp {
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x130b0
+ MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x130a0 /* SODIMM 45 */
>;
};
pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp {
fsl,pins = <
- MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0 /* CD */
+ MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0a0 /* SODIMM 43 */
>;
};
- pinctrl_snvs_usdhc1_sleep_cd: snvs-usdhc1-cd-grp-slp {
+ pinctrl_snvs_usdhc1_sleep_cd: snvs-usdhc1-cd-slp-grp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x0
>;
@@ -553,7 +684,7 @@
pinctrl_snvs_wifi_pdn: snvs-wifi-pdn-grp {
fsl,pins = <
- MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14
+ MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x130a0
>;
};
};
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index f9ce39bf55be..2629aefc19c4 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -3,6 +3,7 @@
// Copyright 2016 Freescale Semiconductor, Inc.
#include "imx6ul.dtsi"
+#include <dt-bindings/input/input.h>
#include "imx6ull-pinfunc.h"
#include "imx6ull-pinfunc-snvs.h"
diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi
new file mode 100644
index 000000000000..0469ca23d8d3
--- /dev/null
+++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&adc2 {
+ status = "okay";
+};
+
+&epxp {
+ status = "okay";
+};
+
+&ecspi3 {
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <
+ &gpio4 11 GPIO_ACTIVE_HIGH
+ &gpio4 23 GPIO_ACTIVE_HIGH
+ >;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs &pinctrl_gpio5>;
+
+ spidev1: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <1>;
+ spi-max-frequency = <23000000>;
+ };
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ vmmc-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4>;
+};
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 3f2746169181..629eeaad58ac 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -1,46 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2020 Toradex
*/
+#include <dt-bindings/input/input.h>
+
/ {
+ aliases {
+ rtc0 = &rtc;
+ rtc1 = &snvs_rtc;
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -52,15 +22,25 @@
clock-frequency = <16000000>;
};
- panel: panel {
- compatible = "edt,et057090dhu";
- backlight = <&bl>;
- power-supply = <&reg_3v3>;
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
- port {
- panel_in: endpoint {
- remote-endpoint = <&lcdif_out>;
- };
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
};
};
@@ -90,14 +70,6 @@
};
};
-&bl {
- brightness-levels = <0 4 8 16 32 64 128 255>;
- default-brightness-level = <6>;
- power-supply = <&reg_3v3>;
-
- status = "okay";
-};
-
&adc1 {
status = "okay";
};
@@ -106,9 +78,11 @@
status = "okay";
};
-&ecspi3 {
+&epxp {
status = "okay";
+};
+&ecspi3 {
mcp2515: can@0 {
compatible = "microchip,mcp2515";
pinctrl-names = "default";
@@ -122,6 +96,14 @@
xceiver-supply = <&reg_5v0>;
status = "okay";
};
+ /* To keep the CAN controller enabled by default,
+ * disable conflicting spidev. This spidev device
+ * enables with the devicetree overlay.
+ */
+ spidev0: spidev@0 {
+ status = "disabled";
+ };
+
};
&fec1 {
@@ -138,25 +120,17 @@
};
};
-&lcdif {
- status = "okay";
-
- port {
- lcdif_out: endpoint {
- remote-endpoint = <&panel_in>;
- };
- };
-};
-
&pwm1 {
status = "okay";
};
&pwm2 {
+ /* The pwm2 should be disabled to enable atmel_mxt_ts touchscreen for adapter. */
status = "okay";
};
&pwm3 {
+ /* The pwm2 should be disabled to enable atmel_mxt_ts touchscreen for adapter. */
status = "okay";
};
@@ -177,12 +151,13 @@
};
&usbotg1 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
status = "okay";
};
&usdhc1 {
- keep-power-in-suspend;
- wakeup-source;
vmmc-supply = <&reg_3v3>;
status = "okay";
};
+
diff --git a/arch/arm/boot/dts/imx7-colibri-iris-v2.dtsi b/arch/arm/boot/dts/imx7-colibri-iris-v2.dtsi
new file mode 100644
index 000000000000..190549461610
--- /dev/null
+++ b/arch/arm/boot/dts/imx7-colibri-iris-v2.dtsi
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 16 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&adc2 {
+ status = "okay";
+};
+
+&epxp {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&gpio2 {
+ /*
+ * uart_b_c_on_x14_enable turns the UART transceiver for UART_B and
+ * UART_C on. If one wants to turn the transceiver off, that property
+ * has to be deleted and the gpio handled in userspace.
+ * The same applies to uart_a_on_x13_enable where the UART_A
+ * transceiver is turned on.
+ */
+ uart_b_c_on_x14_enable {
+ gpio-hog;
+ gpios = <27 GPIO_ACTIVE_HIGH>; /* SODIMM 104 */
+ output-high;
+ };
+};
+
+&gpio5 {
+ uart_a_on_x13_enable {
+ gpio-hog;
+ gpios = <17 GPIO_ACTIVE_HIGH>; /* SODIMM 102 */
+ output-high;
+ };
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&usdhc1 {
+ cap-power-off-card;
+ /delete-property/ keep-power-in-suspend;
+ /delete-property/ no-1-8-v;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7-colibri-iris.dtsi b/arch/arm/boot/dts/imx7-colibri-iris.dtsi
new file mode 100644
index 000000000000..dae3614b6829
--- /dev/null
+++ b/arch/arm/boot/dts/imx7-colibri-iris.dtsi
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2018-2020 Toradex
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio4 7 GPIO_ACTIVE_LOW>;
+ vin-supply = <&reg_5v0>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&adc2 {
+ status = "okay";
+};
+
+&epxp {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ /* The pwm2 should be disabled to enable atmel_mxt_ts touchscreen for adapter. */
+ status = "okay";
+};
+
+&pwm3 {
+ /* The pwm2 should be disabled to enable atmel_mxt_ts touchscreen for adapter . */
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
+
+&gpio2 {
+ /*
+ * uart25 turns the UART transceiver for UART2 and 5 on. If one wants to
+ * turn the transceiver off, that property has to be deleted and the
+ * gpio handled in userspace.
+ * The same applies to uart1_tx_on where the UART transceiver is
+ * turned on.
+ */
+ uart25_tx_on {
+ gpio-hog;
+ gpios = <27 0>; /* SODIMM 104 */
+ output-high;
+ };
+};
+
+&gpio5 {
+ uart1_tx_on {
+ gpio-hog;
+ gpios = <17 0>; /* SODIMM 102 */
+ output-high;
+ };
+};
+
+&usdhc1 {
+ vmmc-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 8bba03de51ad..a0ea6334a7a2 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -1,52 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2021 Toradex
*/
+#include <dt-bindings/pwm/pwm.h>
+
/ {
- bl: backlight {
+ backlight: backlight {
compatible = "pwm-backlight";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_bl_on>;
- pwms = <&pwm1 0 5000000 0>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ power-supply = <&reg_module_3v3>;
+ pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ m4_tcm: tcml@007f8000 {
+ compatible = "fsl, m4_tcml";
+ reg = <0x007f8000 0x8000>;
+ };
+
+ pxp_v4l2_out {
+ compatible = "fsl,imx7d-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", \
+ "fsl,imx6sl-pxp-v4l2";
+ status = "okay";
};
reg_module_3v3: regulator-module-3v3 {
@@ -65,6 +45,33 @@
regulator-always-on;
};
+ reg_module_3v3_eth: regulator-module-3v3-eth {
+ compatible = "regulator-fixed";
+ off-on-delay-us = <200000>;
+ regulator-name = "+V3.3_ETH";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ startup-delay-us = <200000>;
+ vin-supply = <&reg_LDO1>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ m4_reserved: m4@0x9fe00000 {
+ no-map;
+ reg = <0x9fe00000 0x1fffff>;
+ };
+
+ rpmsg_reserved: rpmsg@0x8ff00000 {
+ no-map;
+ reg = <0x8ff00000 0x100000>;
+ };
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "imx7-sgtl5000";
@@ -80,6 +87,11 @@
clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
};
};
+
+ m4_tcm: tcml@007f8000 {
+ compatible = "fsl, m4_tcml";
+ reg = <0x007f8000 0x8000>;
+ };
};
&adc1 {
@@ -98,6 +110,13 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs>;
cs-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
+ };
};
&fec1 {
@@ -114,8 +133,21 @@
assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
assigned-clock-rates = <0>, <100000000>;
phy-mode = "rmii";
- phy-supply = <&reg_LDO1>;
+ phy-supply = <&reg_module_3v3_eth>;
fsl,magic-packet;
+ phy-handle = <&ethphy0>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ max-speed = <100>;
+ micrel,led-mode = <0>;
+ reg = <0>;
+ };
+ };
};
&flexcan1 {
@@ -130,6 +162,184 @@
status = "disabled";
};
+&gpio1 {
+ gpio-line-names = "SODIMM_43",
+ "SODIMM_45",
+ "SODIMM_135",
+ "SODIMM_22",
+ "",
+ "",
+ "SODIMM_37",
+ "SODIMM_29",
+ "SODIMM_59",
+ "SODIMM_28",
+ "SODIMM_30",
+ "SODIMM_67",
+ "",
+ "",
+ "SODIMM_188",
+ "SODIMM_178";
+};
+
+&gpio2 {
+ gpio-line-names = "SODIMM_111",
+ "SODIMM_113",
+ "SODIMM_115",
+ "SODIMM_117",
+ "SODIMM_119",
+ "SODIMM_121",
+ "SODIMM_123",
+ "SODIMM_125",
+ "SODIMM_91",
+ "SODIMM_89",
+ "SODIMM_105",
+ "SODIMM_152",
+ "SODIMM_150",
+ "SODIMM_95",
+ "SODIMM_126",
+ "SODIMM_107",
+ "SODIMM_114",
+ "SODIMM_116",
+ "SODIMM_118",
+ "SODIMM_120",
+ "SODIMM_122",
+ "SODIMM_124",
+ "SODIMM_127",
+ "SODIMM_130",
+ "SODIMM_132",
+ "SODIMM_134",
+ "SODIMM_133",
+ "SODIMM_104",
+ "SODIMM_106",
+ "SODIMM_110",
+ "SODIMM_112",
+ "SODIMM_128";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_56",
+ "SODIMM_44",
+ "SODIMM_68",
+ "SODIMM_82",
+ "SODIMM_93",
+ "SODIMM_76",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_57",
+ "SODIMM_61",
+ "SODIMM_136",
+ "SODIMM_138",
+ "SODIMM_140",
+ "SODIMM_142",
+ "SODIMM_144",
+ "SODIMM_146";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_35",
+ "SODIMM_33",
+ "SODIMM_38",
+ "SODIMM_36",
+ "SODIMM_21",
+ "SODIMM_19",
+ "SODIMM_131",
+ "SODIMM_129",
+ "SODIMM_90",
+ "SODIMM_92",
+ "SODIMM_88",
+ "SODIMM_86",
+ "SODIMM_81",
+ "SODIMM_94",
+ "SODIMM_96",
+ "SODIMM_75",
+ "SODIMM_101",
+ "SODIMM_103",
+ "SODIMM_79",
+ "SODIMM_97",
+ "SODIMM_67",
+ "SODIMM_59",
+ "SODIMM_85",
+ "SODIMM_65";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_69",
+ "SODIMM_71",
+ "SODIMM_73",
+ "SODIMM_47",
+ "SODIMM_190",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_51",
+ "SODIMM_53",
+ "",
+ "",
+ "SODIMM_98",
+ "SODIMM_184",
+ "SODIMM_186",
+ "SODIMM_23",
+ "SODIMM_31",
+ "SODIMM_100",
+ "SODIMM_102";
+};
+
+&gpio6 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_169",
+ "",
+ "",
+ "",
+ "SODIMM_77",
+ "SODIMM_24",
+ "",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_32",
+ "SODIMM_34";
+};
+
+&gpio7 {
+ gpio-line-names = "",
+ "",
+ "SODIMM_63",
+ "SODIMM_55",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_196",
+ "SODIMM_194",
+ "",
+ "SODIMM_99",
+ "",
+ "",
+ "SODIMM_137";
+};
+
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
@@ -160,7 +370,7 @@
VDDD-supply = <&reg_DCDC3>;
};
- ad7879@2c {
+ ad7879_ts: touchscreen@2c {
compatible = "adi,ad7879-1";
reg = <0x2c>;
interrupt-parent = <&gpio1>;
@@ -172,6 +382,7 @@
adi,median-filter-size = /bits/ 8 <2>;
adi,averaging = /bits/ 8 <1>;
adi,conversion-interval = /bits/ 8 <255>;
+ status = "disabled";
};
pmic@33 {
@@ -179,7 +390,7 @@
reg = <0x33>;
regulators {
- reg_DCDC1: DCDC1 { /* V1.0_SOC */
+ reg_DCDC1: DCDC1 { /* V1.0_SOC */
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1100000>;
regulator-boot-on;
@@ -208,7 +419,7 @@
};
reg_LDO1: LDO1 { /* PWR_EN_+V3.3_ETH */
- regulator-min-microvolt = <1800000>;
+ regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
@@ -251,12 +462,174 @@
pinctrl-1 = <&pinctrl_i2c4_recovery>;
scl-gpios = <&gpio7 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio7 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_connector>;
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>; /* SODIMM_107, INT */
+ reset-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* SODIMM_106, RST */
+ status = "disabled";
+ };
+
+
+ /*
+ * the PCAPs use SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3.
+ * so if you enable one of the PCAP controllers disable the pwms
+ */
+ fusion_f0710a: touchscreen@10 {
+ /* TouchRevolution Fusion 7 and 10 multi-touch controller */
+ compatible = "touchrevolution,fusion-f0710a";
+ reg = <0x10>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_adapter>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH /* SODIMM_28, INT */
+ &gpio1 10 GPIO_ACTIVE_LOW /* SODIMM_30, RST */
+ >;
+ status = "disabled";
+ };
};
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
+ display = <&display0>;
+ assigned-clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_SRC>,
+ <&clks IMX7D_PLL_VIDEO_POST_DIV>;
+ assigned-clock-parents = <&clks IMX7D_PLL_VIDEO_POST_DIV>;
+ assigned-clock-rates = <0>, <1031060000>;
+ status = "disabled";
+
+ display0: lcd-display {
+ bits-per-pixel = <16>;
+ bus-width = <18>;
+
+ display-timings {
+ native-mode = <&timing_vga>;
+
+ /* Standard VGA timing */
+ timing_vga: 640x480 {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ hsync-len = <96>;
+ vsync-len = <2>;
+
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ /* WVGA Timing, e.g. EDT ET070080DH6 */
+ timing_wvga: 800x480 {
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <216>;
+ hfront-porch = <40>;
+ vback-porch = <35>;
+ vfront-porch = <10>;
+ hsync-len = <128>;
+ vsync-len = <2>;
+
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ /* WVGA Timing, TouchRevolution Fusion 7" */
+ timing_wvga2: 800x480pixclkact {
+ clock-frequency = <33260000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <216>;
+ hfront-porch = <40>;
+ vback-porch = <35>;
+ vfront-porch = <10>;
+ hsync-len = <128>;
+ vsync-len = <2>;
+
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <1>;
+ };
+
+ /* Standard SVGA timing */
+ timing_svga: 800x600 {
+ clock-frequency = <40000000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <88>;
+ hfront-porch = <40>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ hsync-len = <128>;
+ vsync-len = <4>;
+
+ de-active = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pixelclk-active = <0>;
+ };
+
+ /* Standard XGA timing */
+ timing_xga: 1024x768 {
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ vactive = <768>;
+ hback-porch = <160>;
+ hfront-porch = <24>;
+ vback-porch = <29>;
+ vfront-porch = <3>;
+ hsync-len = <136>;
+ vsync-len = <6>;
+
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ timing_wxga: 1280x800 {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+
+ de-active = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
+
+&ocram {
+ reg = <0x00901000 0xf000>;
+};
+
+&rpmsg {
+ vdev-nums = <1>;
+ reg = <0x8fff0000 0x10000>;
+ status = "okay";
};
&pwm1 {
@@ -279,10 +652,6 @@
pinctrl-0 = <&pinctrl_pwm4>;
};
-&reg_1p0d {
- vin-supply = <&reg_DCDC3>;
-};
-
&sai1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1>;
@@ -316,16 +685,23 @@
};
&usbotg1 {
- dr_mode = "host";
+ dr_mode = "otg";
};
&usdhc1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_cd_usdhc1>;
- no-1-8-v;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_cd_usdhc1>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_cd_usdhc1>;
+ pinctrl-3 = <&pinctrl_usdhc1_sleep &pinctrl_cd_usdhc1_sleep>;
+ bus-width = <4>;
cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
disable-wp;
+ keep-power-in-suspend;
+ no-1-8-v;
vqmmc-supply = <&reg_LDO2>;
+ wakeup-source;
+ status = "disabled";
};
&usdhc3 {
@@ -336,7 +712,6 @@
assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
assigned-clock-rates = <400000000>;
bus-width = <8>;
- fsl,tuning-step = <2>;
vmmc-supply = <&reg_module_3v3>;
vqmmc-supply = <&reg_DCDC3>;
non-removable;
@@ -346,7 +721,21 @@
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
- &pinctrl_gpio7 &pinctrl_usbc_det>;
+ &pinctrl_gpio5 &pinctrl_lvds_transceiver>;
+
+ pinctrl_atmel_adapter: atmeladaptergrp { /* ATMEL MXT TOUCH ADAPTER */
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x74 /* SODIMM_28, INT */
+ MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x14 /* SODIMM_30, RST */
+ >;
+ };
+
+ pinctrl_atmel_connector: atmelconnectorgrp { /* ATMEL MXT TOUCH CONNECTOR */
+ fsl,pins = <
+ MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 /* SODIMM_107, INT */
+ MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x14 /* SODIMM_106, RST */
+ >;
+ };
pinctrl_gpio1: gpio1-grp {
fsl,pins = <
@@ -354,10 +743,7 @@
MX7D_PAD_EPDC_DATA09__GPIO2_IO9 0x14 /* SODIMM 89 */
MX7D_PAD_EPDC_DATA08__GPIO2_IO8 0x74 /* SODIMM 91 */
MX7D_PAD_LCD_RESET__GPIO3_IO4 0x14 /* SODIMM 93 */
- MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 /* SODIMM 95 */
- MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x14 /* SODIMM 99 */
MX7D_PAD_EPDC_DATA10__GPIO2_IO10 0x74 /* SODIMM 105 */
- MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 /* SODIMM 107 */
MX7D_PAD_EPDC_DATA00__GPIO2_IO0 0x14 /* SODIMM 111 */
MX7D_PAD_EPDC_DATA01__GPIO2_IO1 0x14 /* SODIMM 113 */
MX7D_PAD_EPDC_DATA02__GPIO2_IO2 0x14 /* SODIMM 115 */
@@ -374,7 +760,6 @@
MX7D_PAD_SD2_DATA2__GPIO5_IO16 0x14 /* SODIMM 100 */
MX7D_PAD_SD2_DATA3__GPIO5_IO17 0x14 /* SODIMM 102 */
MX7D_PAD_EPDC_GDSP__GPIO2_IO27 0x14 /* SODIMM 104 */
- MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x74 /* SODIMM 106 */
MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x14 /* SODIMM 110 */
MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x14 /* SODIMM 112 */
MX7D_PAD_EPDC_SDCLK__GPIO2_IO16 0x14 /* SODIMM 114 */
@@ -397,7 +782,6 @@
pinctrl_gpio2: gpio2-grp { /* On X22 Camera interface */
fsl,pins = <
- MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x14 /* SODIMM 65 */
MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x74 /* SODIMM 69 */
MX7D_PAD_I2C4_SDA__GPIO4_IO15 0x14 /* SODIMM 75 */
MX7D_PAD_ECSPI1_MISO__GPIO4_IO18 0x14 /* SODIMM 79 */
@@ -430,6 +814,13 @@
>;
};
+ pinctrl_gpio5: spigpios {
+ fsl,pins = <
+ /* CS1 */
+ MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x74 /* SODIMM 65 */
+ >;
+ };
+
pinctrl_gpio7: gpio7-grp { /* Alternatively CAN1 */
fsl,pins = <
MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x14 /* SODIMM 55 */
@@ -591,6 +982,14 @@
>;
};
+ pinctrl_lvds_transceiver: lvds-tx {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x74 /* SODIMM 55 */
+ MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x14 /* SODIMM 63 */
+ MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 /* SODIMM 95 */
+ MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x14 /* SODIMM 99 */
+ >;
+ };
pinctrl_pwm1: pwm1-grp {
fsl,pins = <
MX7D_PAD_GPIO1_IO08__PWM1_OUT 0x79
@@ -671,6 +1070,28 @@
>;
};
+ pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5a
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1a
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5a
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5a
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5a
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5a
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x5b
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x1b
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5b
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5b
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5b
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5b
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX7D_PAD_SD3_CMD__SD3_CMD 0x59
@@ -683,7 +1104,7 @@
MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59
MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59
MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
>;
};
@@ -699,7 +1120,7 @@
MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a
MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a
MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a
>;
};
@@ -715,13 +1136,13 @@
MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b
MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b
MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
>;
};
pinctrl_sai1: sai1-grp {
fsl,pins = <
- MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f
+ MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f
MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC 0x1f
MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30
MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f
@@ -730,7 +1151,24 @@
pinctrl_sai1_mclk: sai1grp_mclk {
fsl,pins = <
- MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x1f
+ MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x1f
+ >;
+ };
+
+ pinctrl_usdhc1_sleep: usdhc1-slp-grp {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x10
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x10
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x10
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x10
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x10
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x10
+ >;
+ };
+
+ pinctrl_cd_usdhc1_sleep: usdhc1-cd-slp-grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO00__GPIO1_IO0 0x0 /* CD */
>;
};
};
@@ -741,12 +1179,17 @@
pinctrl_gpio_lpsr: gpio1-grp {
fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x59
MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x59
MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x59
>;
};
+ pinctrl_gpiokeys: gpiokeysgrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x19
+ >;
+ };
+
pinctrl_i2c1: i2c1-grp {
fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO05__I2C1_SDA 0x4000007f
diff --git a/arch/arm/boot/dts/imx7d-colibri-aster.dts b/arch/arm/boot/dts/imx7d-colibri-aster.dts
new file mode 100644
index 000000000000..7a132d8abf95
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-aster.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri.dtsi"
+#include "imx7-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D on Colibri Aster Board";
+ compatible = "toradex,colibri-imx7d-aster",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts b/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts
new file mode 100644
index 000000000000..f61ad3a1e046
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc-aster.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri-emmc.dtsi"
+#include "imx7-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D 1GB on Colibri Aster Board";
+ compatible = "toradex,colibri-imx7d-emmc-aster",
+ "toradex,colibri-imx7d-emmc",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dts
index 8ee73c870b12..dfc4b31b8811 100644
--- a/arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dts
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2017 Toradex AG
+ * Copyright 2017-2021 Toradex
*/
/dts-v1/;
@@ -10,7 +10,9 @@
/ {
model = "Toradex Colibri iMX7D 1GB (eMMC) on Colibri Evaluation Board V3";
compatible = "toradex,colibri-imx7d-emmc-eval-v3",
- "toradex,colibri-imx7d-emmc", "fsl,imx7d";
+ "toradex,colibri-imx7d-emmc",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
};
&usbotg2 {
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dts b/arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dts
new file mode 100644
index 000000000000..c02276cd4550
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri-emmc.dtsi"
+#include "imx7-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D 1GB on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx7d-emmc-iris-v2",
+ "toradex,colibri-imx7d-emmc",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc-iris.dts b/arch/arm/boot/dts/imx7d-colibri-emmc-iris.dts
new file mode 100644
index 000000000000..26ed20287d11
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc-iris.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri-emmc.dtsi"
+#include "imx7-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D 1GB on Colibri Iris Board";
+ compatible = "toradex,colibri-imx7d-emmc-iris",
+ "toradex,colibri-imx7d-emmc",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
index 898f4b8d7421..06d9daa6926c 100644
--- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
@@ -1,18 +1,58 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2017 Toradex AG
+ * Copyright 2017-2021 Toradex
*/
#include "imx7d.dtsi"
#include "imx7-colibri.dtsi"
/ {
+ aliases {
+ /* add ethernet aliases which is required to proprely pass mac
+ address from bootloader. Also with the update to 5.4.70-2.3.0
+ the kernel hangs without these aliases.
+ */
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ /* the following, together with kernel patches, forces a fixed assignment
+ between device id and usdhc controller */
+ /* i.e. the eMMC on usdhc3 will be /dev/mmcblk0 */
+ mmc0 = &usdhc3; /* eMMC */
+ mmc1 = &usdhc1; /* MMC 4bit slot */
+ };
+
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x40000000>;
};
};
+&gpio6 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_169",
+ "SODIMM_157",
+ "",
+ "SODIMM_163",
+ "SODIMM_77",
+ "SODIMM_24",
+ "",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_32",
+ "SODIMM_34";
+};
+
&usbotg2 {
dr_mode = "host";
};
@@ -20,3 +60,19 @@
&usdhc3 {
status = "okay";
};
+
+&ad7879_ts {
+ status = "disabled";
+};
+
+&backlight {
+ status = "disabled";
+};
+
+&lcdif {
+ status = "disabled";
+};
+
+&atmel_mxt_ts {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts
index 136e11ab4893..a5a993b691e6 100644
--- a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2020 Toradex
*/
/dts-v1/;
@@ -46,10 +9,23 @@
/ {
model = "Toradex Colibri iMX7D on Colibri Evaluation Board V3";
- compatible = "toradex,colibri-imx7d-eval-v3", "toradex,colibri-imx7d",
+ compatible = "toradex,colibri-imx7d-eval-v3",
+ "toradex,colibri-imx7d",
"fsl,imx7d";
};
+/*
+ * The PCAP uses SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3.
+ * So if you enable following PCAP controller, disable pwm2/pwm3 first.
+ */
+&atmel_mxt_ts {
+ pinctrl-0 = <&pinctrl_atmel_adapter>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM_28, INT */
+ reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; /* SODIMM_30, RST */
+ status = "disabled";
+};
+
&usbotg2 {
vbus-supply = <&reg_usbh_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx7d-colibri-iris-v2.dts b/arch/arm/boot/dts/imx7d-colibri-iris-v2.dts
new file mode 100644
index 000000000000..7ddae094529f
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-iris-v2.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2021 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri.dtsi"
+#include "imx7-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx7d-iris-v2",
+ "toradex,colibri-imx7d",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+&gpio2 {
+ /*
+ * This switches the LVDS transceiver to VESA color mapping mode.
+ */
+ LVDS_COLOR_MAP {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>; /* SODIMM 95 */
+ line-name = "LVDS_COLOR_MAP";
+ output-low;
+ };
+};
+
+&gpio7 {
+ /*
+ * This switches the LVDS transceiver to the 24-bit RGB mode.
+ */
+ LVDS_RGB_MODE {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>; /* SODIMM 63 */
+ line-name = "LVDS_RGB_MODE";
+ output-low;
+ };
+
+ /*
+ * This switches the LVDS transceiver to the single-channel
+ * output mode.
+ */
+ LVDS_CH_MODE {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>; /* SODIMM 55 */
+ line-name = "LVDS_CH_MODE";
+ output-high;
+ };
+
+ /* This turns the LVDS transceiver on */
+ LVDS_POWER_ON {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_HIGH>; /* SODIMM 99 */
+ line-name = "LVDS_POWER_ON";
+ output-high;
+ };
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri-iris.dts b/arch/arm/boot/dts/imx7d-colibri-iris.dts
new file mode 100644
index 000000000000..d4b0dafd74a0
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-colibri-iris.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7d-colibri.dtsi"
+#include "imx7-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7D on Colibri Iris Board";
+ compatible = "toradex,colibri-imx7d-iris",
+ "toradex,colibri-imx7d",
+ "toradex,colibri-imx7d",
+ "fsl,imx7d";
+};
+
+/*
+ * The PCAP uses SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3.
+ * So if you enable following PCAP controller, disable pwm2/pwm3 first.
+ */
+&atmel_mxt_ts {
+ pinctrl-0 = <&pinctrl_atmel_adapter>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM_28, INT */
+ reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; /* SODIMM_30, RST */
+ status = "disabled";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usbh_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7d-colibri.dtsi b/arch/arm/boot/dts/imx7d-colibri.dtsi
index e2e327f437e3..9b6866703bca 100644
--- a/arch/arm/boot/dts/imx7d-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7d-colibri.dtsi
@@ -1,59 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2021 Toradex
*/
#include "imx7d.dtsi"
#include "imx7-colibri.dtsi"
/ {
+ aliases {
+ /* add ethernet aliases which is required to proprely pass mac
+ address from bootloader. Also with the update to 5.4.70-2.3.0
+ the kernel hangs without these aliases.
+ */
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
+ };
+
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x20000000>;
};
};
+&ad7879_ts {
+ status = "okay";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
+
+&backlight {
+ status = "okay";
+};
+
&gpmi {
status = "okay";
};
+&lcdif {
+ status = "okay";
+};
+
&usbotg2 {
dr_mode = "host";
};
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index 435100a25aa0..54ffc12a3b5e 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -68,56 +68,6 @@
};
soc {
- busfreq {
- compatible = "fsl,imx_busfreq";
- fsl,max_ddr_freq = <533000000>;
- clocks = <&clks IMX7D_OSC_24M_CLK>, <&clks IMX7D_MAIN_AXI_ROOT_SRC>,
- <&clks IMX7D_AHB_CHANNEL_ROOT_SRC>, <&clks IMX7D_PLL_SYS_PFD0_392M_CLK>,
- <&clks IMX7D_DRAM_ROOT_SRC>, <&clks IMX7D_DRAM_ALT_ROOT_SRC>,
- <&clks IMX7D_PLL_DRAM_MAIN_CLK>, <&clks IMX7D_DRAM_ALT_ROOT_CLK>,
- <&clks IMX7D_PLL_SYS_PFD2_270M_CLK>, <&clks IMX7D_PLL_SYS_PFD1_332M_CLK>,
- <&clks IMX7D_AHB_CHANNEL_ROOT_DIV>, <&clks IMX7D_MAIN_AXI_ROOT_DIV>;
- clock-names = "osc", "axi_sel", "ahb_sel", "pfd0_392m", "dram_root",
- "dram_alt_sel", "pll_dram", "dram_alt_root", "pfd2_270m",
- "pfd1_332m", "ahb", "axi";
- interrupts = <0 112 0x04>, <0 113 0x04>;
- interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
- };
-
- ocrams_ddr: sram@900000 {
- compatible = "fsl,ddr-lpm-sram";
- reg = <0x900000 0x1000>;
- clocks = <&clks IMX7D_OCRAM_CLK>;
- };
-
- ocram: sram@901000 {
- compatible = "mmio-sram";
- reg = <0x901000 0x1f000>;
- clocks = <&clks IMX7D_OCRAM_CLK>;
- };
-
- ocrams: sram@180000 {
- compatible = "fsl,lpm-sram";
- reg = <0x180000 0x8000>;
- clocks = <&clks IMX7D_OCRAM_S_CLK>;
- status = "disabled";
- };
-
- ocram_optee {
- compatible = "fsl,optee-lpm-sram";
- reg = <0x180000 0x8000>;
- overw_reg = <&ocrams_ddr 0x904000 0x1000>,
- <&ocram 0x905000 0x1b000>,
- <&ocrams 0x900000 0x4000>;
- overw_clock = <&ocrams &clks IMX7D_OCRAM_CLK>;
- };
-
- ocrams_mf: sram-mf@900000 {
- compatible = "fsl,mega-fast-sram";
- reg = <0x900000 0x20000>;
- clocks = <&clks IMX7D_OCRAM_CLK>;
- };
-
etm@3007d000 {
compatible = "arm,coresight-etm3x", "arm,primecell";
reg = <0x3007d000 0x1000>;
@@ -165,26 +115,6 @@
status = "disabled";
};
- system_counter_rd: system-counter-rd@306a0000 {
- compatible = "fsl,imx7d-system-counter-rd";
- reg = <0x306a0000 0x10000>;
- status = "disabled";
- };
-
- system_counter_cmp: system-counter-cmp@306b0000 {
- compatible = "fsl,imx7d-system-counter-cmp";
- reg = <0x306b0000 0x10000>;
- status = "disabled";
- };
-
- system_counter_ctrl: system-counter-ctrl@306c0000 {
- compatible = "fsl,imx7d-system-counter-ctrl";
- reg = <0x306c0000 0x10000>;
- interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
-
epdc: epdc@306f0000 {
compatible = "fsl,imx7d-epdc";
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
@@ -196,27 +126,6 @@
status = "disabled";
};
- epxp: epxp@30700000 {
- compatible = "fsl,imx7d-pxp-dma";
- interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0x30700000 0x10000>;
- clocks = <&clks IMX7D_PXP_IPG_CLK>, <&clks IMX7D_PXP_AXI_CLK>;
- clock-names = "pxp_ipg", "pxp_axi";
- status = "disabled";
- };
-
- csi1: csi1@30710000 {
- compatible = "fsl,imx7d-csi", "fsl,imx6s-csi";
- reg = <0x30710000 0x10000>;
- interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_CLK_DUMMY>,
- <&clks IMX7D_CSI_MCLK_ROOT_CLK>,
- <&clks IMX7D_CLK_DUMMY>;
- clock-names = "disp-axi", "csi_mclk", "disp_dcic";
- status = "disabled";
- };
-
mipi_csi: mipi-csi@30750000 {
compatible = "fsl,imx7d-mipi-csi";
reg = <0x30750000 0x10000>;
@@ -232,17 +141,6 @@
/delete-node/ port@1;
};
- mipi_dsi: mipi-dsi@30760000 {
- compatible = "fsl,imx7d-mipi-dsi";
- reg = <0x30760000 0x10000>;
- interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_MIPI_DSI_ROOT_CLK>,
- <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
- clock-names = "mipi_cfg_clk", "mipi_pllref_clk";
- power-domains = <&pgc_mipi_phy>;
- status = "disabled";
- };
-
qosc: qosc@307f0000 {
compatible = "fsl,imx7d-qosc", "syscon";
reg = <0x307f0000 0x4000>;
@@ -250,15 +148,6 @@
};
&aips3 {
- mu: mu@30aa0000 {
- compatible = "fsl,imx7d-mu", "fsl,imx6sx-mu";
- reg = <0x30aa0000 0x10000>;
- interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_MU_ROOT_CLK>;
- clock-names = "mu";
- #mbox-cells = <2>;
- };
-
mu_lp: mu_lp@30aa0000 {
compatible = "fsl,imx7d-mu-lp", "fsl,imx6sx-mu-lp";
reg = <0x30aa0000 0x10000>;
@@ -268,24 +157,6 @@
status = "okay";
};
- sema4: sema4@30ac0000 {
- compatible = "fsl,imx7d-sema4";
- reg = <0x30ac0000 0x10000>;
- interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_SEMA4_HS_ROOT_CLK>;
- clock-names = "sema4";
- status = "okay";
- };
-
- sim1: sim@30b90000 {
- compatible = "fsl,imx7d-sim";
- reg = <0x30b90000 0x10000>;
- interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_SIM1_ROOT_CLK>;
- clock-names = "sim";
- status = "disabled";
- };
-
qspi1: spi@30bb0000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -299,13 +170,6 @@
status = "disabled";
};
- sim2: sim@30ba0000 {
- compatible = "fsl,imx7d-sim";
- reg = <0x30ba0000 0x10000>;
- interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
-
usbotg2: usb@30b20000 {
compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
reg = <0x30b20000 0x200>;
@@ -413,17 +277,11 @@
status = "disabled";
};
- rpmsg: rpmsg{
- compatible = "fsl,imx7d-rpmsg";
- /* up to now, the following channels are used in imx rpmsg
- * - tx1/rx1: messages channel.
- * - general interrupt1: remote proc finish re-init rpmsg stack
- * when A core is partition reset.
- */
- mbox-names = "tx", "rx", "rxdb";
- mboxes = <&mu 0 1
- &mu 1 1
- &mu 3 1>;
+ weim: weim@30bc0000 {
+ compatible = "fsl,imx7d-weim", "fsl,imx6sx-weim", "fsl,imx6q-weim";
+ reg = <0x30bc0000 0x10000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_EIM_ROOT_CLK>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx7s-colibri-aster.dts b/arch/arm/boot/dts/imx7s-colibri-aster.dts
new file mode 100644
index 000000000000..269db1d42e3b
--- /dev/null
+++ b/arch/arm/boot/dts/imx7s-colibri-aster.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7s-colibri.dtsi"
+#include "imx7-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7S on Colibri Aster Board";
+ compatible = "toradex,colibri-imx7s-aster",
+ "toradex,colibri-imx7s",
+ "toradex,colibri-imx7s",
+ "fsl,imx7s";
+};
diff --git a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts
index bd2a49c1ade6..6a1dbc6bc6ce 100644
--- a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2020 Toradex
*/
/dts-v1/;
@@ -46,6 +9,8 @@
/ {
model = "Toradex Colibri iMX7S on Colibri Evaluation Board V3";
- compatible = "toradex,colibri-imx7s-eval-v3", "toradex,colibri-imx7s",
+ compatible = "toradex,colibri-imx7s-eval-v3",
+ "toradex,colibri-imx7s",
+ "toradex,colibri-imx7s",
"fsl,imx7s";
};
diff --git a/arch/arm/boot/dts/imx7s-colibri-iris-v2.dts b/arch/arm/boot/dts/imx7s-colibri-iris-v2.dts
new file mode 100644
index 000000000000..9b16c50a9ca6
--- /dev/null
+++ b/arch/arm/boot/dts/imx7s-colibri-iris-v2.dts
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2021 Toradex
+ */
+
+/dts-v1/;
+#include "imx7s-colibri.dtsi"
+#include "imx7-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7S on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx7s-iris-v2",
+ "toradex,colibri-imx7s",
+ "toradex,colibri-imx7s",
+ "fsl,imx7s";
+};
+
+&gpio2 {
+ /*
+ * This switches the LVDS transceiver to VESA color mapping mode.
+ */
+ LVDS_COLOR_MAP {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>; /* SODIMM 95 */
+ line-name = "LVDS_COLOR_MAP";
+ output-low;
+ };
+};
+
+&gpio7 {
+ /*
+ * This switches the LVDS transceiver to the 24-bit RGB mode.
+ */
+ LVDS_RGB_MODE {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>; /* SODIMM 63 */
+ line-name = "LVDS_RGB_MODE";
+ output-low;
+ };
+
+ /*
+ * This switches the LVDS transceiver to the single-channel
+ * output mode.
+ */
+ LVDS_CH_MODE {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>; /* SODIMM 55 */
+ line-name = "LVDS_CH_MODE";
+ output-high;
+ };
+
+ /* This turns the LVDS transceiver on */
+ LVDS_POWER_ON {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_HIGH>; /* SODIMM 99 */
+ line-name = "LVDS_POWER_ON";
+ output-high;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7s-colibri-iris.dts b/arch/arm/boot/dts/imx7s-colibri-iris.dts
new file mode 100644
index 000000000000..84473f7468be
--- /dev/null
+++ b/arch/arm/boot/dts/imx7s-colibri-iris.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+/dts-v1/;
+#include "imx7s-colibri.dtsi"
+#include "imx7-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX7S on Colibri Iris Board";
+ compatible = "toradex,colibri-imx7s-iris",
+ "toradex,colibri-imx7s",
+ "toradex,colibri-imx7s",
+ "fsl,imx7s";
+};
diff --git a/arch/arm/boot/dts/imx7s-colibri.dtsi b/arch/arm/boot/dts/imx7s-colibri.dtsi
index 6d16e32aed89..e6c80d3ae29c 100644
--- a/arch/arm/boot/dts/imx7s-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7s-colibri.dtsi
@@ -1,55 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
- * Copyright 2016 Toradex AG
- *
- * 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.
+ * Copyright 2016-2020 Toradex
*/
#include "imx7s.dtsi"
#include "imx7-colibri.dtsi"
/ {
+ aliases {
+ /* add ethernet aliases which is required to proprely pass mac
+ address from bootloader. Also with the update to 5.4.70-2.3.0
+ the kernel hangs without these aliases.
+ */
+ ethernet0 = &fec1;
+ };
+
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x10000000>;
};
};
+&ad7879_ts {
+ status = "okay";
+};
+
+&atmel_mxt_ts {
+ status = "okay";
+};
+
+&backlight {
+ status = "okay";
+};
+
&gpmi {
status = "okay";
};
+
+&lcdif {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 8903c9b04ffe..9ebb7be72867 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -60,6 +60,22 @@
clock-frequency = <792000000>;
clock-latency = <61036>; /* two CLK32 periods */
clocks = <&clks IMX7D_CLK_ARM>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
+ nvmem-cells = <&cpu_speed_grade>;
+ nvmem-cell-names = "speed_grade";
+ };
+ };
+
+ cpu0_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-792000000 {
+ opp-hz = /bits/ 64 <792000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <150000>;
+ opp-supported-hw = <0xf>, <0xf>;
};
};
@@ -151,6 +167,56 @@
interrupt-parent = <&gpc>;
ranges;
+ busfreq {
+ compatible = "fsl,imx_busfreq";
+ fsl,max_ddr_freq = <533000000>;
+ clocks = <&clks IMX7D_OSC_24M_CLK>, <&clks IMX7D_MAIN_AXI_ROOT_SRC>,
+ <&clks IMX7D_AHB_CHANNEL_ROOT_SRC>, <&clks IMX7D_PLL_SYS_PFD0_392M_CLK>,
+ <&clks IMX7D_DRAM_ROOT_SRC>, <&clks IMX7D_DRAM_ALT_ROOT_SRC>,
+ <&clks IMX7D_PLL_DRAM_MAIN_CLK>, <&clks IMX7D_DRAM_ALT_ROOT_CLK>,
+ <&clks IMX7D_PLL_SYS_PFD2_270M_CLK>, <&clks IMX7D_PLL_SYS_PFD1_332M_CLK>,
+ <&clks IMX7D_AHB_CHANNEL_ROOT_DIV>, <&clks IMX7D_MAIN_AXI_ROOT_DIV>;
+ clock-names = "osc", "axi_sel", "ahb_sel", "pfd0_392m", "dram_root",
+ "dram_alt_sel", "pll_dram", "dram_alt_root", "pfd2_270m",
+ "pfd1_332m", "ahb", "axi";
+ interrupts = <0 112 0x04>, <0 113 0x04>;
+ interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
+ };
+
+ ocrams_ddr: sram@900000 {
+ compatible = "fsl,ddr-lpm-sram";
+ reg = <0x900000 0x1000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocram: sram@901000 {
+ compatible = "mmio-sram";
+ reg = <0x901000 0x1f000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocrams: sram@180000 {
+ compatible = "fsl,lpm-sram";
+ reg = <0x180000 0x8000>;
+ clocks = <&clks IMX7D_OCRAM_S_CLK>;
+ status = "disabled";
+ };
+
+ ocrams_mf: sram-mf@900000 {
+ compatible = "fsl,mega-fast-sram";
+ reg = <0x900000 0x20000>;
+ clocks = <&clks IMX7D_OCRAM_CLK>;
+ };
+
+ ocram_optee {
+ compatible = "fsl,optee-lpm-sram";
+ reg = <0x180000 0x8000>;
+ overw_reg = <&ocrams_ddr 0x904000 0x1000>,
+ <&ocram 0x905000 0x1b000>,
+ <&ocrams 0x900000 0x4000>;
+ overw_clock = <&ocrams &clks IMX7D_OCRAM_CLK>;
+ };
+
funnel@30041000 {
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0x30041000 0x1000>;
@@ -729,6 +795,38 @@
status = "disabled";
};
+ epxp: epxp@30700000 {
+ compatible = "fsl,imx7d-pxp-dma";
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x30700000 0x10000>;
+ clocks = <&clks IMX7D_PXP_IPG_CLK>, <&clks IMX7D_PXP_AXI_CLK>;
+ clock-names = "pxp_ipg", "pxp_axi";
+ status = "disabled";
+ };
+
+ csi1: csi1@30710000 {
+ compatible = "fsl,imx7d-csi", "fsl,imx6s-csi";
+ reg = <0x30710000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_CLK_DUMMY>,
+ <&clks IMX7D_CSI_MCLK_ROOT_CLK>,
+ <&clks IMX7D_CLK_DUMMY>;
+ clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+ status = "disabled";
+ };
+
+ mipi_dsi: mipi-dsi@30760000 {
+ compatible = "fsl,imx7d-mipi-dsi";
+ reg = <0x30760000 0x10000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_MIPI_DSI_ROOT_CLK>,
+ <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
+ clock-names = "mipi_cfg_clk", "mipi_pllref_clk";
+ power-domains = <&pgc_mipi_phy>;
+ status = "disabled";
+ };
+
pwm1: pwm@30660000 {
compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
reg = <0x30660000 0x10000>;
@@ -773,6 +871,26 @@
status = "disabled";
};
+ system_counter_rd: system-counter-rd@306a0000 {
+ compatible = "fsl,imx7d-system-counter-rd";
+ reg = <0x306a0000 0x10000>;
+ status = "disabled";
+ };
+
+ system_counter_cmp: system-counter-cmp@306b0000 {
+ compatible = "fsl,imx7d-system-counter-cmp";
+ reg = <0x306b0000 0x10000>;
+ status = "disabled";
+ };
+
+ system_counter_ctrl: system-counter-ctrl@306c0000 {
+ compatible = "fsl,imx7d-system-counter-ctrl";
+ reg = <0x306c0000 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
csi: csi@30710000 {
compatible = "fsl,imx7-csi";
reg = <0x30710000 0x10000>;
@@ -1119,6 +1237,15 @@
status = "disabled";
};
+ mu: mu@30aa0000 {
+ compatible = "fsl,imx7d-mu", "fsl,imx6sx-mu";
+ reg = <0x30aa0000 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_MU_ROOT_CLK>;
+ clock-names = "mu";
+ #mbox-cells = <2>;
+ };
+
mu0a: mailbox@30aa0000 {
compatible = "fsl,imx7s-mu", "fsl,imx6sx-mu";
reg = <0x30aa0000 0x10000>;
@@ -1138,6 +1265,15 @@
status = "disabled";
};
+ sema4: sema4@30ac0000 {
+ compatible = "fsl,imx7d-sema4";
+ reg = <0x30ac0000 0x10000>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_SEMA4_HS_ROOT_CLK>;
+ clock-names = "sema4";
+ status = "okay";
+ };
+
usbotg1: usb@30b10000 {
compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
reg = <0x30b10000 0x200>;
@@ -1217,6 +1353,22 @@
status = "disabled";
};
+ sim1: sim@30b90000 {
+ compatible = "fsl,imx7d-sim";
+ reg = <0x30b90000 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_SIM1_ROOT_CLK>;
+ clock-names = "sim";
+ status = "disabled";
+ };
+
+ sim2: sim@30ba0000 {
+ compatible = "fsl,imx7d-sim";
+ reg = <0x30ba0000 0x10000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
sdma: sdma@30bd0000 {
compatible = "fsl,imx7d-sdma", "fsl,imx35-sdma";
reg = <0x30bd0000 0x10000>;
@@ -1247,6 +1399,20 @@
fsl,num-rx-queues = <3>;
status = "disabled";
};
+
+ rpmsg: rpmsg{
+ compatible = "fsl,imx7d-rpmsg";
+ /* up to now, the following channels are used in imx rpmsg
+ * - tx1/rx1: messages channel.
+ * - general interrupt1: remote proc finish re-init rpmsg stack
+ * when A core is partition reset.
+ */
+ mbox-names = "tx", "rx", "rxdb";
+ mboxes = <&mu 0 1
+ &mu 1 1
+ &mu 3 1>;
+ status = "disabled";
+ };
};
dma_apbh: dma-apbh@33000000 {
diff --git a/arch/arm/configs/apalis_imx6_defconfig b/arch/arm/configs/apalis_imx6_defconfig
new file mode 100644
index 000000000000..2851bc6b1c2e
--- /dev/null
+++ b/arch/arm/configs/apalis_imx6_defconfig
@@ -0,0 +1,525 @@
+CONFIG_BUILD_SALT="n"
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_IO_URING is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+CONFIG_HIGHMEM=y
+# CONFIG_ARM_MODULE_PLTS is not set
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_SECCOMP=y
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+# CONFIG_STACKPROTECTOR is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_CMA=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_MASQ=y
+CONFIG_NFT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_L2TP=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_TSN=y
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTUSB_BCM is not set
+# CONFIG_BT_HCIBTUSB_RTL is not set
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_IMX6_HOST=y
+CONFIG_PCI_IMX6_EP=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_CFI_STAA=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+CONFIG_HNS_DSAF=m
+CONFIG_HNS_ENET=m
+CONFIG_E1000E=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
+CONFIG_SKY2=m
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NETERION is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+CONFIG_QCOM_EMAC=m
+CONFIG_SMC91X=m
+CONFIG_SMC911X=m
+CONFIG_SMSC911X=m
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+CONFIG_STMMAC_ETH=m
+# CONFIG_DWMAC_IMX8 is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9800=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+# CONFIG_WLAN_VENDOR_MARVELL is not set
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_NXP is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_WLAN_VENDOR_REALTEK is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_IVSHMEM_NET=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_FUSION_F0710A=m
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_GPIO=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_HWMON is not set
+CONFIG_SENSORS_MAG3110=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_SANYO_DECODER=y
+CONFIG_IR_SHARP_DECODER=y
+CONFIG_IR_MCE_KBD_DECODER=y
+CONFIG_IR_XMP_DECODER=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CSI_CAMERA=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_TVIN_ADV7280=m
+CONFIG_MXC_TVIN_MAX9526=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_VIDEO_MXC_PXP_V4L2=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_LVDS=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_LEGACY=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB_MXS=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_OVERLAY=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_HIDRAW=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_GADGET_UAC1=y
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=m
+CONFIG_MXC_PXP_V2=y
+CONFIG_STAGING=y
+CONFIG_R8188EU=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_STMPE_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX27=y
+# CONFIG_IMX_IRQSTEER is not set
+# CONFIG_RESET_DISPMIX is not set
+# CONFIG_PHY_FSL_IMX_PCIE is not set
+CONFIG_MXC_IPU=y
+CONFIG_MXC_MLB150=y
+CONFIG_MXC_IPU_V3_PRE=y
+CONFIG_MXC_HDMI_CEC=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_OVERLAY_FS=y
+# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_SECURITYFS=y
+CONFIG_LSM="n"
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_ECHAINIV=m
+CONFIG_CRYPTO_TLS=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CFB=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_OFB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=320
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/colibri-imx6ull_defconfig b/arch/arm/configs/colibri-imx6ull_defconfig
new file mode 100644
index 000000000000..97bd20332669
--- /dev/null
+++ b/arch/arm/configs/colibri-imx6ull_defconfig
@@ -0,0 +1,496 @@
+CONFIG_BUILD_SALT="n"
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_IO_URING is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6UL=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_ERRATA_857271=y
+CONFIG_ARM_ERRATA_857272=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+# CONFIG_ARM_MODULE_PLTS is not set
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+# CONFIG_STACKPROTECTOR is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_CMA=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_MASQ=y
+CONFIG_NFT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_L2TP=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_TSN=y
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTUSB_BCM is not set
+# CONFIG_BT_HCIBTUSB_RTL is not set
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE 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_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=m
+CONFIG_SMC911X=m
+CONFIG_SMSC911X=m
+# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9800=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_WLAN_VENDOR_REALTEK is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_SNVS_PWRKEY=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=y
+CONFIG_TOUCHSCREEN_AD7879_I2C=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_FUSION_F0710A=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_GPIO=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_HWMON is not set
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_SANYO_DECODER=y
+CONFIG_IR_SHARP_DECODER=y
+CONFIG_IR_MCE_KBD_DECODER=y
+CONFIG_IR_XMP_DECODER=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+# CONFIG_USB_GSPCA is not set
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_IMX_PXP=y
+CONFIG_FB=y
+CONFIG_FB_MXS=y
+# CONFIG_FB_MXC_EDID is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=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_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_HIDRAW=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_GADGET_UAC1=y
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=m
+CONFIG_MXS_DMA=y
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_V3=y
+# CONFIG_MX3_IPU is not set
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_STAGING=y
+CONFIG_R8188EU=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_IMX7D_ADC=y
+CONFIG_VF610_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX27=y
+# CONFIG_IMX_IRQSTEER is not set
+# CONFIG_RESET_DISPMIX is not set
+CONFIG_GENERIC_PHY=y
+# CONFIG_PHY_FSL_IMX_PCIE is not set
+CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_NVMEM_SNVS_LPGPR=y
+CONFIG_MXC_SIM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_OVERLAY_FS=y
+# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_SECURITYFS=y
+CONFIG_LSM="n"
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_ECHAINIV=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
+CONFIG_CRYPTO_DEV_MXS_DCP=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=256
+CONFIG_CMA_SIZE_PERCENTAGE=50
+CONFIG_CMA_SIZE_SEL_MIN=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/colibri_imx6_defconfig b/arch/arm/configs/colibri_imx6_defconfig
new file mode 100644
index 000000000000..f0d29b557fe0
--- /dev/null
+++ b/arch/arm/configs/colibri_imx6_defconfig
@@ -0,0 +1,525 @@
+CONFIG_BUILD_SALT="n"
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_IO_URING is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+CONFIG_HIGHMEM=y
+# CONFIG_ARM_MODULE_PLTS is not set
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_SECCOMP=y
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+# CONFIG_STACKPROTECTOR is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_CMA=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_MASQ=y
+CONFIG_NFT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_L2TP=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTUSB_BCM is not set
+# CONFIG_BT_HCIBTUSB_RTL is not set
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_CFI_STAA=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE 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_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=m
+CONFIG_SMC911X=m
+CONFIG_SMSC911X=m
+# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9800=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+# CONFIG_WLAN_VENDOR_MARVELL is not set
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_NXP is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_WLAN_VENDOR_REALTEK is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_FUSION_F0710A=m
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_GPIO=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_HWMON is not set
+CONFIG_SENSORS_MAG3110=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_SANYO_DECODER=y
+CONFIG_IR_SHARP_DECODER=y
+CONFIG_IR_MCE_KBD_DECODER=y
+CONFIG_IR_XMP_DECODER=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CSI_CAMERA=m
+CONFIG_MXC_VADC=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV5640_V2=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_TVIN_ADV7280=m
+CONFIG_MXC_TVIN_MAX9526=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_VIDEO_MXC_PXP_V4L2=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_LVDS=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_LEGACY=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB_MXS=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_OVERLAY=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_HIDRAW=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_GADGET_UAC1=y
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=m
+CONFIG_MXC_PXP_V2=y
+CONFIG_STAGING=y
+CONFIG_R8188EU=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_STMPE_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX27=y
+# CONFIG_IMX_IRQSTEER is not set
+# CONFIG_RESET_DISPMIX is not set
+# CONFIG_PHY_FSL_IMX_PCIE is not set
+CONFIG_MXC_IPU=y
+CONFIG_MXC_MLB150=y
+CONFIG_MXC_IPU_V3_PRE=y
+CONFIG_MXC_HDMI_CEC=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_OVERLAY_FS=y
+# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_SECURITYFS=y
+CONFIG_LSM="n"
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_ECHAINIV=m
+CONFIG_CRYPTO_TLS=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CFB=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_OFB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=256
+CONFIG_CMA_SIZE_PERCENTAGE=50
+CONFIG_CMA_SIZE_SEL_MIN=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/colibri_imx7_defconfig b/arch/arm/configs/colibri_imx7_defconfig
new file mode 100644
index 000000000000..7745b4c869dd
--- /dev/null
+++ b/arch/arm/configs/colibri_imx7_defconfig
@@ -0,0 +1,511 @@
+CONFIG_BUILD_SALT="n"
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_IO_URING is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX7D=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_SMP=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+# CONFIG_ARM_MODULE_PLTS is not set
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ARM_IMX_CPUFREQ_DT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+# CONFIG_STACKPROTECTOR is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_CMA=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_MASQ=y
+CONFIG_NFT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_L2TP=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_TSN=y
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTUSB_BCM is not set
+# CONFIG_BT_HCIBTUSB_RTL is not set
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_ECC_SW_BCH=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_IPVLAN=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE 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_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=m
+CONFIG_SMC911X=m
+CONFIG_SMSC911X=m
+# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9800=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+# CONFIG_WLAN_VENDOR_MARVELL is not set
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_WLAN_VENDOR_REALTEK is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=y
+CONFIG_TOUCHSCREEN_AD7879_I2C=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_FUSION_F0710A=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX_GPIO=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_SPI_NXP_FLEXSPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_HWMON is not set
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_RN5T618_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_RN5T618=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_RN5T618=y
+CONFIG_RC_CORE=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_SANYO_DECODER=y
+CONFIG_IR_SHARP_DECODER=y
+CONFIG_IR_MCE_KBD_DECODER=y
+CONFIG_IR_XMP_DECODER=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+# CONFIG_USB_GSPCA is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_PXP_V4L2=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
+CONFIG_VIDEO_IMX_PXP=y
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+CONFIG_FB=y
+# CONFIG_FB_MX3 is not set
+CONFIG_FB_MXS=y
+# CONFIG_FB_MXC_EDID is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=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_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_ASRC=y
+CONFIG_SND_SOC_FSL_SPDIF=y
+CONFIG_SND_SOC_IMX_AUDMUX=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_AUDMIX=y
+CONFIG_SND_SOC_SGTL5000=m
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_HIDRAW=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_GADGET_UAC1=y
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=m
+CONFIG_MXS_DMA=y
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_V3=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_STAGING=y
+CONFIG_R8188EU=m
+CONFIG_MAILBOX=y
+CONFIG_IMX_MBOX=y
+# CONFIG_IMX_GPCV2_PM_DOMAINS is not set
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_IMX7D_ADC=y
+CONFIG_VF610_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX27=y
+# CONFIG_IMX_IRQSTEER is not set
+# CONFIG_RESET_DISPMIX is not set
+# CONFIG_PHY_FSL_IMX_PCIE is not set
+CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_MXC_SIM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_OVERLAY_FS=y
+# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_SECURITYFS=y
+CONFIG_LSM="n"
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_ECHAINIV=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=192
+CONFIG_CMA_SIZE_PERCENTAGE=50
+CONFIG_CMA_SIZE_SEL_MIN=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SINK_TPIU=y
+CONFIG_CORESIGHT_SINK_ETBV10=y
+CONFIG_CORESIGHT_SOURCE_ETM3X=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 8233e5a4f615..511b52e09199 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -104,7 +104,8 @@ CONFIG_CFG80211_WEXT=y
CONFIG_MAC80211=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
-CONFIG_PCI_IMX6=y
+CONFIG_PCI_IMX6_HOST=y
+CONFIG_PCI_IMX6_EP=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
@@ -504,6 +505,13 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_JFFS2_FS=y
CONFIG_UBIFS_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
diff --git a/arch/arm/configs/nit6xlite_defconfig b/arch/arm/configs/nit6xlite_defconfig
new file mode 100644
index 000000000000..dfc1a38b3c4a
--- /dev/null
+++ b/arch/arm/configs/nit6xlite_defconfig
@@ -0,0 +1,303 @@
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_GPIO_PCA953X=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_IMX6=y
+CONFIG_RC_MODE_IN_EP_RC_SYS=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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=y
+CONFIG_NETFILTER=y
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CMA=y
+CONFIG_CMA_SIZE_MBYTES=256
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=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_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS 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_NET_VENDOR_WIZNET is not set
+CONFIG_MICREL_PHY=y
+CONFIG_BRCMFMAC=m
+CONFIG_IWLWIFI=m
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AR1020_I2C=y
+CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH=y
+CONFIG_TOUCHSCREEN_FT5X06=y
+CONFIG_TOUCHSCREEN_FT5X06_SINGLE_TOUCH=y
+CONFIG_TOUCHSCREEN_TSC2004=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_SENSORS_MAG3110=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_VIDEO_V4L2_INT_DEVICE=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_SOC_CAMERA=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+# CONFIG_DVB_AU8522_V4L is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+CONFIG_DRM=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB=y
+CONFIG_FB_MXS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_MIPI_DSI=y
+CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_PHY=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_MXC_ASRC=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_LEDS_CLASS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_ISL1208=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+# CONFIG_MX3_IPU is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_IMX_SDMA=y
+CONFIG_STAGING=y
+CONFIG_COMMON_CLK_DEBUG=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index bb18ed0539f4..d78e5baf42cf 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -120,6 +120,9 @@ void machine_power_off(void)
if (pm_power_off)
pm_power_off();
+ /* shoud pm_power_off not exist of fail, then at least do a halt*/
+ pr_err("%s pm_power_off() did return\n",__func__);
+ machine_halt();
}
/*
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index fc8f5b5cd3e8..ca53fb4bdcbc 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -46,6 +46,7 @@ config HAVE_IMX_GPCV2
config HAVE_IMX_MMDC
bool
+ select HAVE_IMX_BUSFREQ
config HAVE_IMX_AMP
bool
@@ -525,6 +526,7 @@ config SOC_IMX6SLL
bool "i.MX6 SoloLiteLite support"
select PINCTRL_IMX6SLL
select SOC_IMX6
+ select ARM_IMX6Q_CPUFREQ
help
This enables support for Freescale i.MX6 SoloLiteLite processor.
@@ -547,6 +549,7 @@ config SOC_IMX6UL
select PINCTRL_IMX6UL
select SOC_IMX6
select ARM_ERRATA_814220
+ select ARM_IMX6Q_CPUFREQ
help
This enables support for Freescale i.MX6 UltraLite processor.
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index ddfe6b0b8291..02a4477c1ffb 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -82,7 +82,7 @@ obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
obj-$(CONFIG_HAVE_IMX_SRC) += src.o
obj-$(CONFIG_HAVE_IMX_DDRC) += ddrc.o
obj-$(CONFIG_HAVE_IMX_MU) += mu.o
-ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
+ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7D)$(CONFIG_SOC_LS1021A),)
AFLAGS_headsmp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
@@ -91,7 +91,7 @@ obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o ddr3_freq_imx6.o smp_wfe_imx6.o \
lpddr2_freq_imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o lpddr2_freq_imx6.o
obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o lpddr2_freq_imx6sll.o
-obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o ddr3_freq_imx6sx.o lpddr2_freq_imx6sx.o
+obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o ddr3_freq_imx6sx.o smp_wfe_imx6.o lpddr2_freq_imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o ddr3_freq_imx6sx.o lpddr2_freq_imx6sx.o
obj-$(CONFIG_SOC_IMX7D_CA7) += mach-imx7d.o pm-imx7.o ddr3_freq_imx7d.o smp_wfe.o \
lpddr3_freq_imx.o suspend-imx7.o
diff --git a/arch/arm/mach-imx/busfreq-imx.c b/arch/arm/mach-imx/busfreq-imx.c
index 88135aa414f9..1eefe589d816 100644
--- a/arch/arm/mach-imx/busfreq-imx.c
+++ b/arch/arm/mach-imx/busfreq-imx.c
@@ -180,6 +180,8 @@ static int busfreq_notify(enum busfreq_event event)
return notifier_to_errno(ret);
}
+#ifdef CONFIG_HAVE_IMX_BUSFREQ
+
int register_busfreq_notifier(struct notifier_block *nb)
{
return raw_notifier_chain_register(&busfreq_notifier_chain, nb);
@@ -192,6 +194,10 @@ int unregister_busfreq_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_busfreq_notifier);
+#endif /* CONFIG_HAVE_IMX_BUSFREQ */
+
+#ifdef CONFIG_ARM_IMX6Q_CPUFREQ
+
static struct clk *origin_step_parent;
/*
@@ -220,6 +226,16 @@ static void imx6ull_lower_cpu_rate(bool enter)
clk_set_parent(pll1_bypass_clk, pll1_clk);
}
}
+#else
+static void imx6ull_lower_cpu_rate(bool enter)
+{
+ /* this stub should never be called.
+ configure with CONFIG_ARM_IMX6Q_CPUFREQ
+ */
+ (void) enter;
+ BUG();
+}
+#endif
/*
* enter_lpm_imx6_up and exit_lpm_imx6_up is used by
@@ -818,6 +834,8 @@ static int set_high_bus_freq(int high_bus_freq)
return 0;
}
+#ifdef CONFIG_HAVE_IMX_BUSFREQ
+
void request_bus_freq(enum bus_freq_mode mode)
{
mutex_lock(&bus_freq_mutex);
@@ -949,6 +967,8 @@ int get_bus_freq_mode(void)
}
EXPORT_SYMBOL(get_bus_freq_mode);
+#endif /* CONFIG_HAVE_IMX_BUSFREQ */
+
static struct map_desc ddr_iram_io_desc __initdata = {
/* .virtual and .pfn are run-time assigned */
.length = SZ_1M,
diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
index 4f22b8f0d02b..f45ca55f984d 100644
--- a/arch/arm/mach-imx/cpuidle-imx6ul.c
+++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
@@ -93,10 +93,12 @@ static void (*imx6ul_wfi_in_iram_fn)(void __iomem *iram_vbase);
static int imx6ul_idle_finish(unsigned long val)
{
+#if defined(CONFIG_ARM_PSCI_FW)
if (psci_ops.cpu_suspend)
psci_ops.cpu_suspend(MX6UL_POWERDWN_IDLE_PARAM,
__pa(cpu_resume));
else
+#endif
imx6ul_wfi_in_iram_fn(wfi_iram_base);
return 0;
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 838d93381c07..d4461648b8e9 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -150,6 +150,7 @@ unsigned int imx_gpc_is_mf_mix_off(void)
static void imx_gpc_mf_mix_off(void)
{
+#if 0
int i;
for (i = 0; i < IMR_NUM; i++)
@@ -160,6 +161,7 @@ static void imx_gpc_mf_mix_off(void)
pr_info("Turn off M/F mix!\n");
/* turn off mega/fast mix */
writel_relaxed(0x1, gpc_base + GPC_PGC_MF_PDN);
+#endif
}
void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw)
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 730ce83eee0e..a22cff64c631 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -15,6 +15,7 @@
#include <linux/irqchip.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/pm_opp.h>
@@ -33,6 +34,37 @@
#include "cpuidle.h"
#include "hardware.h"
+/* The PCIe switch on the Apalis Evaluation Board requires to have its reset
+ * deasserted some time before the reset of the downstream endpoints.
+ * The downstream endpoints use RESET_MOCI while the PCIe switch uses GPIO7
+ * for reset.
+ * Handle RESET_MOCI when the PCIe driver is not configured or disabled in
+ * the device tree */
+static void apalis_reset_moci(void)
+{
+ struct device_node *np;
+ int ret, reset_moci_gpio, no_pcie;
+#ifdef CONFIG_PCI_IMX6
+ no_pcie = 0;
+#else
+ no_pcie = 1;
+#endif
+
+ np = of_find_node_by_name(NULL, "pcie");
+ if (!of_device_is_available(np) || no_pcie) {
+ reset_moci_gpio = of_get_named_gpio(np, "reset-ep-gpio", 0);
+ if (gpio_is_valid(reset_moci_gpio)) {
+ ret = gpio_request_one(reset_moci_gpio,
+ GPIOF_OUT_INIT_LOW,
+ "RESET_MOCI");
+ if (ret) {
+ pr_err("%s(): unable to get RESET_MOCI gpio"
+ " from dt pcie node\n", __func__);
+ }
+ }
+ }
+}
+
/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
static int ksz9021rn_phy_fixup(struct phy_device *phydev)
{
@@ -61,6 +93,14 @@ static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
phy_write(dev, 0x0e, val);
}
+static int mmd_read_reg(struct phy_device *dev, int device, int reg)
+{
+ phy_write(dev, 0x0d, device);
+ phy_write(dev, 0x0e, reg);
+ phy_write(dev, 0x0d, (1 << 14) | device);
+ return phy_read(dev, 0x0e);
+}
+
static int ksz9031rn_phy_fixup(struct phy_device *dev)
{
/*
@@ -74,6 +114,33 @@ static int ksz9031rn_phy_fixup(struct phy_device *dev)
return 0;
}
+#define KSZ9131_RXTXDLL_BYPASS 12
+
+static int ksz9131rn_phy_fixup(struct phy_device *dev)
+{
+ int tmp;
+
+ tmp = mmd_read_reg(dev, 2, 0x4c);
+ /* disable rxdll bypass (enable 2ns skew delay on RXC) */
+ tmp &= ~(1 << KSZ9131_RXTXDLL_BYPASS);
+ mmd_write_reg(dev, 2, 0x4c, tmp);
+
+ tmp = mmd_read_reg(dev, 2, 0x4d);
+ /* disable txdll bypass (enable 2ns skew delay on TXC) */
+ tmp &= ~(1 << KSZ9131_RXTXDLL_BYPASS);
+ mmd_write_reg(dev, 2, 0x4d, tmp);
+
+ /*
+ * Subtract ~0.6ns from txdll = ~1.4ns delay.
+ * leave RXC path untouched
+ */
+ mmd_write_reg(dev, 2, 4, 0x007d);
+ mmd_write_reg(dev, 2, 6, 0xdddd);
+ mmd_write_reg(dev, 2, 8, 0x0007);
+
+ return 0;
+}
+
/*
* fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
* as they are used for slots1-7 PERST#
@@ -179,6 +246,8 @@ static void __init imx6q_enet_phy_init(void)
ksz9021rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
ksz9031rn_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_KSZ9131, MICREL_PHY_ID_MASK,
+ ksz9131rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
ar8031_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,
@@ -341,6 +410,9 @@ static void __init imx6q_init_machine(void)
imx6q_csi_mux_init();
cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
imx6q_axi_init();
+
+ if (of_machine_is_compatible("toradex,apalis_imx6q"))
+ apalis_reset_moci();
}
static void __init imx6q_init_late(void)
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 7ad5e6f240dd..57681fbe7a19 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2015 Freescale Semiconductor, Inc.
*/
+#include <linux/clk.h>
#include <linux/irqchip.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
@@ -83,15 +84,48 @@ static void __init imx7d_enet_mdio_fixup(void)
static void __init imx7d_enet_clk_sel(void)
{
+ struct device_node *np = NULL;
+ struct clk *enet_out_clk;
struct regmap *gpr;
gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
- if (!IS_ERR(gpr)) {
- regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
- regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
- } else {
+ if (IS_ERR(gpr)) {
pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+ return;
}
+
+ do {
+ int id;
+ u32 clk_sel_mask, clk_dir_mask;
+
+ np = of_find_compatible_node(np, NULL, "fsl,imx7d-fec");
+ if (!np)
+ return;
+
+ /* Determine controller ID by ethernet alias */
+ id = of_alias_get_id(np, "ethernet");
+ clk_sel_mask = id == 0 ? IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK :
+ IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK;
+ clk_dir_mask = id == 0 ? IMX7D_GPR1_ENET1_CLK_DIR_MASK :
+ IMX7D_GPR1_ENET2_CLK_DIR_MASK;
+
+ enet_out_clk = of_clk_get_by_name(np, "enet_out");
+
+ if (IS_ERR(enet_out_clk)) {
+ pr_info("%s: fec%d: failed to get enet_out clock, assuming ext. clock source\n",
+ __func__, id + 1);
+ /* use external clock for PHY */
+ regmap_update_bits(gpr, IOMUXC_GPR1, clk_sel_mask, clk_sel_mask);
+ regmap_update_bits(gpr, IOMUXC_GPR1, clk_dir_mask, 0);
+ } else {
+ pr_info("%s: fec%d: found enet_out clock, assuming internal clock source\n",
+ __func__, id + 1);
+ /* use internal clock generation and output it to PHY */
+ regmap_update_bits(gpr, IOMUXC_GPR1, clk_sel_mask, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1, clk_dir_mask, clk_dir_mask);
+ clk_put(enet_out_clk);
+ }
+ } while (np);
}
static inline void imx7d_enet_init(void)
diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c
index 1a250b07b256..f8844e6a3bee 100644
--- a/arch/arm/mach-imx/mu.c
+++ b/arch/arm/mach-imx/mu.c
@@ -37,6 +37,8 @@
#define MU_LPM_HANDSHAKE_INDEX 0
#define MU_RPMSG_HANDSHAKE_INDEX 1
+#define MU_LPM_M4_LPM_READY 0xFFFF4444
+#define MU_LPM_M4_LPM_SLEEP 0xFFFF5555
#define MU_LPM_BUS_HIGH_READY_FOR_M4 0xFFFF6666
#define MU_LPM_M4_FREQ_CHANGE_READY 0xFFFF7777
#define MU_LPM_M4_REQUEST_HIGH_BUS 0x2222CCCC
@@ -279,10 +281,13 @@ int imx_mu_lpm_ready(bool ready)
writel_relaxed(val & ~BIT(0), mu_base + MX7ULP_MU_CR);
} else {
val = readl_relaxed(mu_base + MU_ACR);
- if (ready)
+ if (ready) {
+ imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX, MU_LPM_M4_LPM_READY);
writel_relaxed(val | BIT(0), mu_base + MU_ACR);
- else
+ } else {
+ imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX, MU_LPM_M4_LPM_SLEEP);
writel_relaxed(val & ~BIT(0), mu_base + MU_ACR);
+ }
}
return 0;
}
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index a77289a33c89..f425abbc3d85 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -752,10 +752,12 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
static int imx6q_suspend_finish(unsigned long val)
{
+#if defined(CONFIG_ARM_PSCI_FW)
if (psci_ops.cpu_suspend) {
return psci_ops.cpu_suspend(MX6Q_SUSPEND_PARAM,
__pa(cpu_resume));
}
+#endif
if (!imx6_suspend_in_ocram_fn) {
cpu_do_idle();
@@ -1080,8 +1082,10 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
return -EINVAL;
}
+#if defined(CONFIG_ARM_PSCI_FW)
if (psci_ops.cpu_suspend)
return ret;
+#endif
/*
* 16KB is allocated for IRAM TLB, but only up 8k is for kernel TLB,
@@ -1299,17 +1303,60 @@ void __init imx6_pm_ccm_init(const char *ccm_compat)
writel_relaxed(val, ccm_base + CLPCR);
}
+void imx6_stop_mode_poweroff(void)
+{
+ /* compare with imx6q_set_lpm */
+ u32 val = readl_relaxed(ccm_base + CLPCR);
+
+ val &= ~BM_CLPCR_LPM;
+ /*
+ * mask all but the currently running processor,
+ * otherwise we will not enter stop mode
+ */
+ val |= smp_processor_id() != 0 ? BM_CLPCR_MASK_CORE0_WFI : 0;
+ val |= smp_processor_id() != 1 ? BM_CLPCR_MASK_CORE1_WFI : 0;
+ val |= smp_processor_id() != 2 ? BM_CLPCR_MASK_CORE2_WFI : 0;
+ val |= smp_processor_id() != 3 ? BM_CLPCR_MASK_CORE3_WFI : 0;
+ val |= BM_CLPCR_MASK_SCU_IDLE;
+ val |= 0x2 << BP_CLPCR_LPM;
+ val |= 0x3 << BP_CLPCR_STBY_COUNT;
+ val |= BM_CLPCR_VSTBY;
+ val |= BM_CLPCR_SBYOS;
+ val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+
+ imx_gpc_hwirq_unmask(0);
+ writel_relaxed(val, ccm_base + CLPCR);
+ imx_gpc_hwirq_mask(0);
+ imx_gpc_mask_all();
+ cpu_do_idle();
+}
+
void __init imx6q_pm_init(void)
{
if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
imx6_pm_common_init(&imx6q_lpddr2_pm_data);
else
imx6_pm_common_init(&imx6q_pm_data);
+ /*
+ * if no specific power off function in board file, power off system by
+ * stop mode
+ */
+ if (!pm_power_off)
+ if (of_machine_is_compatible("toradex,apalis_imx6q"))
+ pm_power_off = imx6_stop_mode_poweroff;
}
void __init imx6dl_pm_init(void)
{
imx6_pm_common_init(&imx6dl_pm_data);
+
+ /*
+ * if no specific power off function in board file, power off system by
+ * stop mode
+ */
+ if (!pm_power_off)
+ if (of_machine_is_compatible("toradex,colibri_imx6dl"))
+ pm_power_off = imx6_stop_mode_poweroff;
}
void __init imx6sl_pm_init(void)
diff --git a/arch/arm/mach-imx/pm-imx7.c b/arch/arm/mach-imx/pm-imx7.c
index e59cbee6dfc2..0f0bbb2366bc 100644
--- a/arch/arm/mach-imx/pm-imx7.c
+++ b/arch/arm/mach-imx/pm-imx7.c
@@ -44,6 +44,7 @@
#include "hardware.h"
#include "cpuidle.h"
+#define MX7_SUSPEND_OCRAM_OFFSET 0x4000
#define MX7_SUSPEND_OCRAM_SIZE 0x1000
#define MX7_MAX_DDRC_NUM 32
#define MX7_MAX_DDRC_PHY_NUM 16
@@ -892,7 +893,8 @@ static int __init imx7_dt_find_lpsram(unsigned long node, const char *uname,
if (!prop)
return -EINVAL;
- lpram_addr = be32_to_cpup(prop);
+ /* Add offset so we can use a full vector table for M4 */
+ lpram_addr = be32_to_cpup(prop) + MX7_SUSPEND_OCRAM_OFFSET;
/* We need to create a 1M page table entry. */
iram_tlb_io_desc.virtual = IMX_IO_P2V(lpram_addr & 0xFFF00000);
@@ -1148,7 +1150,7 @@ void __init imx7d_pm_init(void)
/* map the m4 bootrom from dtb */
np = of_find_node_by_path(
- "/soc/sram@00180000");
+ "/soc/sram@180000");
if (np)
m4_bootrom_base = of_iomap(np, 0);
WARN_ON(!m4_bootrom_base);
@@ -1176,13 +1178,13 @@ void __init imx7d_pm_init(void)
WARN_ON(!lpm_ocram_saved_in_ddr);
np = of_find_node_by_path(
- "/soc/aips-bus@30000000/iomuxc@30330000");
+ "/soc/bus@30000000/pinctrl@30330000");
if (np)
iomuxc_base = of_iomap(np, 0);
WARN_ON(!iomuxc_base);
np = of_find_node_by_path(
- "/soc/aips-bus@30000000/gpt@302d0000");
+ "/soc/bus@30000000/timer@302d0000");
if (np)
gpt1_base = of_iomap(np, 0);
WARN_ON(!gpt1_base);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 15c8733ce44a..8b2d8df31241 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -340,7 +340,12 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
pgprot_t prot, struct page **ret_page,
const void *caller, bool want_vaddr);
+#if IS_ENABLED(CONFIG_VIDEO_TW68)
+#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_32M
+#else
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
+#endif
+
static struct gen_pool *atomic_pool __ro_after_init;
static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE;
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 3e9642a8514f..c87b39bab0e8 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -54,7 +54,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb imx8mm-evk-rpmsg.dtb imx8mm-evk-rm67191
imx8mm-ddr4-evk-revb-rm67191.dtb imx8mm-ddr3l-val.dtb \
imx8mm-evk-pcie-ep.dtb imx8mm-ddr4-evk-pcie-ep.dtb \
imx8mm-evk-usd-wifi.dtb \
- imx8mm-evk-qca-wifi.dtb
+ imx8mm-evk-qca-wifi.dtb \
+ imx8mm-verdin-nonwifi-dahlia.dtb \
+ imx8mm-verdin-nonwifi-dev.dtb \
+ imx8mm-verdin-wifi-dahlia.dtb \
+ imx8mm-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk-ak4497.dtb imx8mm-evk-ak5558.dtb imx8mm-evk-audio-tdm.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk-8mic-revE.dtb imx8mm-evk-8mic-swpdm.dtb \
imx8mm-evk-iqaudio-dacplus.dtb imx8mm-evk-iqaudio-dacpro.dtb imx8mm-evk-hifiberry-dacplus.dtb
@@ -73,7 +77,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb imx8mp-evk-root.dtb imx8mp-evk-inmate.d
imx8mp-evk-dsp.dtb imx8mp-evk-ov2775.dtb imx8mp-evk-basler.dtb imx8mp-evk-pcie-ep.dtb \
imx8mp-evk-spdif-lb.dtb imx8mp-evk-dsp-lpa.dtb imx8mp-evk-ov2775-ov5640.dtb \
imx8mp-evk-basler-ov5640.dtb imx8mp-evk-dual-ov2775.dtb \
- imx8mp-evk-basler-ov2775.dtb imx8mp-evk-dual-basler.dtb
+ imx8mp-evk-basler-ov2775.dtb imx8mp-evk-dual-basler.dtb \
+ imx8mp-verdin-nonwifi-dahlia.dtb \
+ imx8mp-verdin-nonwifi-dev.dtb \
+ imx8mp-verdin-wifi-dahlia.dtb \
+ imx8mp-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-ddr4-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mq-evk-pcie1-m2.dtb imx8mq-evk-usd-wifi.dtb \
imx8mq-evk-usdhc2-m2.dtb imx8mq-evk-pcie-ep.dtb
@@ -106,7 +114,15 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qm-mek.dtb imx8qm-mek-ov5640.dtb \
imx8qm-lpddr4-val-lpspi.dtb imx8qm-lpddr4-val-lpspi-slave.dtb \
imx8qm-mek-dsi-rm67191.dtb imx8qm-lpddr4-val-dp.dtb\
imx8qp-lpddr4-val.dtb imx8dm-lpddr4-val.dtb imx8qm-pcieax2pciebx1.dtb \
- imx8qm-mek-esai.dtb imx8qm-mek-vop.dtb
+ imx8qm-mek-esai.dtb imx8qm-mek-vop.dtb \
+ imx8qm-apalis-eval.dtb \
+ imx8qm-apalis-ixora-v1.1.dtb \
+ imx8qm-apalis-v1.1-eval.dtb \
+ imx8qm-apalis-v1.1-ixora-v1.1.dtb \
+ imx8qm-apalis-v1.1-ixora-v1.2.dtb \
+ imx8qp-apalis-v1.1-eval.dtb \
+ imx8qp-apalis-v1.1-ixora-v1.1.dtb \
+ imx8qp-apalis-v1.1-ixora-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-mek-dom0.dtb imx8qm-mek-domu.dtb \
imx8qm-mek-root.dtb imx8qm-mek-inmate.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
@@ -153,7 +169,17 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb imx8qxp-mek-dsp.dtb imx8qxp-mek-ov5640
imx8qxp-lpddr4-val-lpspi.dtb imx8qxp-lpddr4-val-lpspi-slave.dtb \
imx8qxp-lpddr4-val-spdif.dtb imx8qxp-lpddr4-val-gpmi-nand.dtb imx8dxp-lpddr4-val.dtb \
imx8qxp-17x17-val.dtb imx8dx-lpddr4-val.dtb imx8dx-17x17-val.dtb \
- imx8qxp-lpddr4-val-mlb.dtb imx8qxp-mek-vop.dtb
+ imx8qxp-lpddr4-val-mlb.dtb imx8qxp-mek-vop.dtb \
+ imx8qxp-colibri-aster.dtb \
+ imx8dx-colibri-aster.dtb \
+ imx8qxp-colibri-eval-v3.dtb \
+ imx8dx-colibri-eval-v3.dtb \
+ imx8qxp-colibri-iris.dtb \
+ imx8dx-colibri-iris.dtb \
+ imx8dx-colibri-iris-v2.dtb \
+ imx8qxp-colibri-iris-v2.dtb \
+ imx8qxp-colibri-lvds-single-channel.dtb \
+ imx8qxp-colibri-lvds-dual-channel.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek-dom0.dtb imx8qxp-mek-root.dtb \
imx8qxp-mek-inmate.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb imx8dxl-evk-rpmsg.dtb \
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
new file mode 100644
index 000000000000..0a4fe3898993
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2020 Toradex
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &rtc;
+ };
+
+ reg_usb_host_vbus: regulator-usb-host-vbus {
+ regulator-name = "VCC USBH2(ABCD) / USBH(3|4)";
+ };
+};
+
+&adc0 {
+ status = "okay";
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ status = "okay";
+};
+
+&backlight {
+ default-brightness-level = <4>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ pwms = <&pwm_lvds1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "okay";
+};
+
+&dc0_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc0_pc {
+ status = "okay";
+};
+
+&dc0_prg1 {
+ status = "okay";
+};
+
+&dc0_prg2 {
+ status = "okay";
+};
+
+&dc0_prg3 {
+ status = "okay";
+};
+
+&dc0_prg4 {
+ status = "okay";
+};
+
+&dc0_prg5 {
+ status = "okay";
+};
+
+&dc0_prg6 {
+ status = "okay";
+};
+
+&dc0_prg7 {
+ status = "okay";
+};
+
+&dc0_prg8 {
+ status = "okay";
+};
+
+&dc0_prg9 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc1_pc {
+ status = "okay";
+};
+
+&dc1_prg1 {
+ status = "okay";
+};
+
+&dc1_prg2 {
+ status = "okay";
+};
+
+&dc1_prg3 {
+ status = "okay";
+};
+
+&dc1_prg4 {
+ status = "okay";
+};
+
+&dc1_prg5 {
+ status = "okay";
+};
+
+&dc1_prg6 {
+ status = "okay";
+};
+
+&dc1_prg7 {
+ status = "okay";
+};
+
+&dc1_prg8 {
+ status = "okay";
+};
+
+&dc1_prg9 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&flexcan1 {
+ status = "okay";
+};
+
+&flexcan2 {
+ status = "okay";
+};
+
+&gpu_3d0{
+ status = "okay";
+};
+
+&gpu_3d1{
+ status = "okay";
+};
+
+/* Apalis I2C1 */
+&i2c2 {
+ status = "okay";
+
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio5>, <&pinctrl_gpio6>;
+ reg = <0x4a>;
+ interrupt-parent = <&lsio_gpio4>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>; /* Apalis GPIO5 */
+ reset-gpios = <&lsio_gpio4 2 GPIO_ACTIVE_HIGH>; /* Apalis GPIO6 */
+ status = "disabled";
+ };
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/* Apalis I2C3 (CAM) */
+&i2c3 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&irqsteer_csi1 {
+ status = "okay";
+};
+
+/* Apalis SPI1 */
+&lpspi0 {
+ status = "okay";
+};
+
+/* Apalis SPI2 */
+&lpspi2 {
+ status = "okay";
+};
+
+/* Apalis UART3 */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Apalis UART1 */
+&lpuart1 {
+ status = "okay";
+};
+
+/* Apalis UART4 */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Apalis UART2 */
+&lpuart3 {
+ status = "okay";
+};
+
+/* Apalis PCIE1 */
+&pciea{
+ status = "okay";
+};
+
+/* Apalis PWM3, MXM3 pin 6 */
+&pwm0 {
+ status = "okay";
+};
+
+/* Apalis PWM4, MXM3 pin 8 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Apalis PWM1, MXM3 pin 2 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Apalis PWM2, MXM3 pin 4 */
+&pwm3 {
+ status = "okay";
+};
+
+&pwm_lvds1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_bkl>;
+ status = "okay";
+};
+
+&sai1 {
+ status = "okay";
+};
+
+&sai5 {
+ status = "okay";
+};
+
+&sai5_lpcg {
+ status = "okay";
+};
+
+/* Apalis SATA1 */
+&sata {
+ status = "okay";
+};
+
+/* Apalis SPDIF1 */
+&spdif0 {
+ status = "okay";
+};
+
+&spdif1 {
+ status = "okay";
+};
+
+&spdif1_lpcg {
+ status = "okay";
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis USBO1 */
+&usbotg1 {
+ status = "okay";
+};
+
+/* Apalis USBH4 SuperSpeed */
+&usbotg3 {
+ dr_mode = "host";
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ status = "okay";
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
new file mode 100644
index 000000000000..53f56dc8f536
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2020 Toradex
+ */
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &rtc;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds_ixora>;
+
+ /* MXM3_188 */
+ led4-green {
+ label = "LED_4_GREEN";
+ gpios = <&lsio_gpio5 27 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_178 */
+ led4-red {
+ label = "LED_4_RED";
+ gpios = <&lsio_gpio5 29 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_152 */
+ led5-green {
+ label = "LED_5_GREEN";
+ gpios = <&lsio_gpio5 20 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_156 */
+ led5-red {
+ label = "LED_5_RED";
+ gpios = <&lsio_gpio5 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb_host_vbus: regulator-usb-host-vbus {
+ regulator-name = "VCC_USBH(2|4)";
+ };
+};
+
+&adc0 {
+ status = "okay";
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ status = "okay";
+};
+
+&backlight {
+ default-brightness-level = <4>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ pwms = <&pwm_lvds1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "okay";
+};
+
+&dc0_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc0_pc {
+ status = "okay";
+};
+
+&dc0_prg1 {
+ status = "okay";
+};
+
+&dc0_prg2 {
+ status = "okay";
+};
+
+&dc0_prg3 {
+ status = "okay";
+};
+
+&dc0_prg4 {
+ status = "okay";
+};
+
+&dc0_prg5 {
+ status = "okay";
+};
+
+&dc0_prg6 {
+ status = "okay";
+};
+
+&dc0_prg7 {
+ status = "okay";
+};
+
+&dc0_prg8 {
+ status = "okay";
+};
+
+&dc0_prg9 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc1_pc {
+ status = "okay";
+};
+
+&dc1_prg1 {
+ status = "okay";
+};
+
+&dc1_prg2 {
+ status = "okay";
+};
+
+&dc1_prg3 {
+ status = "okay";
+};
+
+&dc1_prg4 {
+ status = "okay";
+};
+
+&dc1_prg5 {
+ status = "okay";
+};
+
+&dc1_prg6 {
+ status = "okay";
+};
+
+&dc1_prg7 {
+ status = "okay";
+};
+
+&dc1_prg8 {
+ status = "okay";
+};
+
+&dc1_prg9 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&gpu_3d0{
+ status = "okay";
+};
+
+&gpu_3d1{
+ status = "okay";
+};
+
+/* Apalis I2C1 */
+&i2c2 {
+ status = "okay";
+
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio5>, <&pinctrl_gpio6>;
+ reg = <0x4a>;
+ interrupt-parent = <&lsio_gpio4>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>; /* Apalis GPIO5 */
+ reset-gpios = <&lsio_gpio4 2 GPIO_ACTIVE_HIGH>; /* Apalis GPIO6 */
+ status = "disabled";
+ };
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/* Apalis I2C3 (CAM) */
+&i2c3 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_cam1_gpios>, <&pinctrl_dap1_gpios>,
+ <&pinctrl_esai0_gpios>, <&pinctrl_fec2_gpios>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>, <&pinctrl_gpio_usbh_oc_n>,
+ <&pinctrl_lpuart1ctrl>, <&pinctrl_lvds0_i2c0_gpio>,
+ <&pinctrl_lvds1_i2c0_gpios>, <&pinctrl_mipi_dsi_0_1_en>,
+ <&pinctrl_mipi_dsi1_gpios>, <&pinctrl_mlb_gpios>,
+ <&pinctrl_qspi1a_gpios>, <&pinctrl_sata1_act>,
+ <&pinctrl_sim0_gpios>, <&pinctrl_usdhc1_gpios>,
+ <&pinctrl_uart24_forceoff>;
+
+ pinctrl_leds_ixora: ledsixoragrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_DATA1_LSIO_GPIO5_IO27 0x41 /* LED_4_GREEN */
+ IMX8QM_USDHC2_DATA3_LSIO_GPIO5_IO29 0x41 /* LED_4_RED */
+ IMX8QM_USDHC1_DATA5_LSIO_GPIO5_IO20 0x41 /* LED_5_GREEN */
+ IMX8QM_USDHC1_DATA6_LSIO_GPIO5_IO21 0x41 /* LED_5_RED */
+ >;
+ };
+
+ pinctrl_uart24_forceoff: uart24forceoffgrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_CMD_LSIO_GPIO5_IO25 0x21
+ >;
+ };
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&irqsteer_csi1 {
+ status = "okay";
+};
+
+&lsio_gpio5 {
+ ngpios = <32>;
+ gpio-line-names = "gpio5-00", "gpio5-01", "gpio5-02", "gpio5-03",
+ "gpio5-04", "gpio5-05", "gpio5-06", "gpio5-07",
+ "gpio5-08", "gpio5-09", "gpio5-10", "gpio5-11",
+ "gpio5-12", "gpio5-13", "gpio5-14", "gpio5-15",
+ "gpio5-16", "gpio5-17", "gpio5-18", "gpio5-19",
+ "LED-5-GREEN", "LED-5-RED", "gpio5-22", "gpio5-23",
+ "gpio5-24", "UART24-FORCEOFF", "gpio5-26",
+ "LED-4-GREEN", "gpio5-28", "LED-4-RED", "gpio5-30",
+ "gpio5-31";
+};
+
+/* Apalis SPI1 */
+&lpspi0 {
+ status = "okay";
+};
+
+/* Apalis SPI2 */
+&lpspi2 {
+ status = "okay";
+};
+
+/* Apalis UART3 */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Apalis UART1 */
+&lpuart1 {
+ status = "okay";
+};
+
+/* Apalis UART4 */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Apalis UART2 */
+&lpuart3 {
+ status = "okay";
+};
+
+/* Apalis PCIE1 */
+&pciea{
+ status = "okay";
+};
+
+/* Apalis PWM3, MXM3 pin 6 */
+&pwm0 {
+ status = "okay";
+};
+
+/* Apalis PWM4, MXM3 pin 8 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Apalis PWM1, MXM3 pin 2 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Apalis PWM2, MXM3 pin 4 */
+&pwm3 {
+ status = "okay";
+};
+
+&pwm_lvds1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_bkl>;
+ status = "okay";
+};
+
+&sai1 {
+ status = "okay";
+};
+
+&sai5 {
+ status = "okay";
+};
+
+&sai5_lpcg {
+ status = "okay";
+};
+
+/* Apalis SATA1 */
+&sata {
+ status = "okay";
+};
+
+/* Apalis SPDIF1 */
+&spdif0 {
+ status = "okay";
+};
+
+&spdif1 {
+ status = "okay";
+};
+
+&spdif1_lpcg {
+ status = "okay";
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis USBO1 */
+&usbotg1 {
+ status = "okay";
+};
+
+/* Apalis USBH4 SuperSpeed */
+&usbotg3 {
+ dr_mode = "host";
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
new file mode 100644
index 000000000000..ba1f4c846820
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
@@ -0,0 +1,532 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2021 Toradex
+ */
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &rtc;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds_ixora>;
+
+ /* MXM3_188 */
+ led4-green {
+ label = "LED_4_GREEN";
+ gpios = <&lsio_gpio5 27 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_178 */
+ led4-red {
+ label = "LED_4_RED";
+ gpios = <&lsio_gpio5 29 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_152 */
+ led5-green {
+ label = "LED_5_GREEN";
+ gpios = <&lsio_gpio5 20 GPIO_ACTIVE_HIGH>;
+ };
+ /* MXM3_156 */
+ led5-red {
+ label = "LED_5_RED";
+ gpios = <&lsio_gpio5 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_usb_host_vbus: regulator-usb-host-vbus {
+ regulator-name = "VCC_USBH(2|4)";
+ };
+
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_vmmc>;
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+
+ /* MMC1_PWR_CTRL */
+ gpio = <&lsio_gpio5 19 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_can1_supply: regulator-can1-supply {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can1_power>;
+ regulator-name = "can1_supply";
+ gpio = <&lsio_gpio5 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can2_supply: regulator-can2-supply {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sata1_act>;
+ regulator-name = "can2_supply";
+ gpio = <&lsio_gpio2 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+};
+
+&adc0 {
+ status = "okay";
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&amix {
+ status = "okay";
+};
+
+&asrc0 {
+ status = "okay";
+};
+
+&backlight {
+ default-brightness-level = <4>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ pwms = <&pwm_lvds1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "okay";
+};
+
+&dc0_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc0_pc {
+ status = "okay";
+};
+
+&dc0_prg1 {
+ status = "okay";
+};
+
+&dc0_prg2 {
+ status = "okay";
+};
+
+&dc0_prg3 {
+ status = "okay";
+};
+
+&dc0_prg4 {
+ status = "okay";
+};
+
+&dc0_prg5 {
+ status = "okay";
+};
+
+&dc0_prg6 {
+ status = "okay";
+};
+
+&dc0_prg7 {
+ status = "okay";
+};
+
+&dc0_prg8 {
+ status = "okay";
+};
+
+&dc0_prg9 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc1_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc1_pc {
+ status = "okay";
+};
+
+&dc1_prg1 {
+ status = "okay";
+};
+
+&dc1_prg2 {
+ status = "okay";
+};
+
+&dc1_prg3 {
+ status = "okay";
+};
+
+&dc1_prg4 {
+ status = "okay";
+};
+
+&dc1_prg5 {
+ status = "okay";
+};
+
+&dc1_prg6 {
+ status = "okay";
+};
+
+&dc1_prg7 {
+ status = "okay";
+};
+
+&dc1_prg8 {
+ status = "okay";
+};
+
+&dc1_prg9 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&dpu2 {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&gpu_3d0{
+ status = "okay";
+};
+
+&gpu_3d1{
+ status = "okay";
+};
+
+/* Apalis I2C1 */
+&i2c2 {
+ status = "okay";
+
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio5>, <&pinctrl_gpio6>;
+ reg = <0x4a>;
+ interrupt-parent = <&lsio_gpio4>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>; /* Apalis GPIO5 */
+ reset-gpios = <&lsio_gpio4 2 GPIO_ACTIVE_HIGH>; /* Apalis GPIO6 */
+ status = "disabled";
+ };
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+/* Apalis I2C3 (CAM) */
+&i2c3 {
+ status = "okay";
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_cam1_gpios>, <&pinctrl_dap1_gpios>,
+ <&pinctrl_esai0_gpios>, <&pinctrl_fec2_gpios>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>, <&pinctrl_gpio_usbh_oc_n>,
+ <&pinctrl_lpuart1ctrl>, <&pinctrl_lvds0_i2c0_gpio>,
+ <&pinctrl_lvds1_i2c0_gpios>, <&pinctrl_mipi_dsi_0_1_en>,
+ <&pinctrl_mipi_dsi1_gpios>, <&pinctrl_mlb_gpios>,
+ <&pinctrl_qspi1a_gpios>, <&pinctrl_sim0_gpios>,
+ <&pinctrl_usdhc1_gpios>, <&pinctrl_uart24_forceoff>;
+
+ pinctrl_leds_ixora: ledsixoragrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_DATA1_LSIO_GPIO5_IO27 0x41 /* LED_4_GREEN */
+ IMX8QM_USDHC2_DATA3_LSIO_GPIO5_IO29 0x41 /* LED_4_RED */
+ IMX8QM_USDHC1_DATA5_LSIO_GPIO5_IO20 0x41 /* LED_5_GREEN */
+ IMX8QM_USDHC1_DATA6_LSIO_GPIO5_IO21 0x41 /* LED_5_RED */
+ >;
+ };
+
+ pinctrl_uart24_forceoff: uart24forceoffgrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_CMD_LSIO_GPIO5_IO25 0x21
+ >;
+ };
+
+ /* Apalis MMC1_CD# */
+ pinctrl_mmc1_cd_4bit: mmc1cdgrp_4bit {
+ fsl,pins = <
+ IMX8QM_ESAI1_TX1_LSIO_GPIO2_IO09 0x00000021
+ >;
+ };
+
+ /* Apalis MMC1 */
+ pinctrl_usdhc2_4bit: usdhc2grp_4bit {
+ fsl,pins = <
+ IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+
+ /* On-module PMIC use */
+ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ /* Apalis MMC1_CD# */
+ pinctrl_mmc1_cd_4bit_sleep: mmc1cdgrp_4bit {
+ fsl,pins = <
+ IMX8QM_ESAI1_TX1_LSIO_GPIO2_IO09 0x04000041
+ >;
+ };
+
+ /* Apalis MMC1 */
+ pinctrl_usdhc2_4bit_sleep: usdhc2grp_4bit {
+ fsl,pins = <
+ IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x04000041
+ IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x04000041
+ IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x04000041
+ IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x04000041
+ IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x04000041
+ IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x04000041
+
+ /* On-module PMIC use */
+ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x04000041
+ >;
+ };
+
+ /* PMIC MMC1 power-switch */
+ pinctrl_enable_3v3_vmmc: enable_3v3_vmmc {
+ fsl,pins = <
+ IMX8QM_USDHC1_DATA4_LSIO_GPIO5_IO19 0x00000021 /* MXM3_148, PMIC */
+ >;
+ };
+
+ /* FlexCAN PMIC */
+ pinctrl_enable_can1_power: enable_can1_power {
+ fsl,pins = <
+ IMX8QM_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021 /* MXM3_158, PMIC */
+ >;
+ };
+
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&irqsteer_csi1 {
+ status = "okay";
+};
+
+&lsio_gpio5 {
+ ngpios = <32>;
+ gpio-line-names = "gpio5-00", "gpio5-01", "gpio5-02", "gpio5-03",
+ "gpio5-04", "gpio5-05", "gpio5-06", "gpio5-07",
+ "gpio5-08", "gpio5-09", "gpio5-10", "gpio5-11",
+ "gpio5-12", "gpio5-13", "gpio5-14", "gpio5-15",
+ "gpio5-16", "gpio5-17", "gpio5-18", "gpio5-19",
+ "LED-5-GREEN", "LED-5-RED", "gpio5-22", "gpio5-23",
+ "gpio5-24", "UART24-FORCEOFF", "gpio5-26",
+ "LED-4-GREEN", "gpio5-28", "LED-4-RED", "gpio5-30",
+ "gpio5-31";
+};
+
+/* Apalis SPI1 */
+&lpspi0 {
+ status = "okay";
+};
+
+/* Apalis SPI2 */
+&lpspi2 {
+ status = "okay";
+};
+
+/* Apalis UART3 */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Apalis UART1 */
+&lpuart1 {
+ status = "okay";
+};
+
+/* Apalis UART4 */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Apalis UART2 */
+&lpuart3 {
+ status = "okay";
+};
+
+/* Apalis PCIE1 */
+&pciea{
+ status = "okay";
+};
+
+/* Apalis PWM3, MXM3 pin 6 */
+&pwm0 {
+ status = "okay";
+};
+
+/* Apalis PWM4, MXM3 pin 8 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Apalis PWM1, MXM3 pin 2 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Apalis PWM2, MXM3 pin 4 */
+&pwm3 {
+ status = "okay";
+};
+
+&pwm_lvds1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_bkl>;
+ status = "okay";
+};
+
+&sai1 {
+ status = "okay";
+};
+
+&sai5 {
+ status = "okay";
+};
+
+&sai5_lpcg {
+ status = "okay";
+};
+
+/* Apalis SATA1 */
+&sata {
+ status = "okay";
+};
+
+/* Apalis SPDIF1 */
+&spdif0 {
+ status = "okay";
+};
+
+&spdif1 {
+ status = "okay";
+};
+
+&spdif1_lpcg {
+ status = "okay";
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis USBO1 */
+&usbotg1 {
+ status = "okay";
+};
+
+/* Apalis USBH4 SuperSpeed */
+&usbotg3 {
+ dr_mode = "host";
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2_4bit>, <&pinctrl_mmc1_cd_4bit>;
+ pinctrl-1 = <&pinctrl_usdhc2_4bit>, <&pinctrl_mmc1_cd_4bit>;
+ pinctrl-2 = <&pinctrl_usdhc2_4bit>, <&pinctrl_mmc1_cd_4bit>;
+ pinctrl-3 = <&pinctrl_usdhc2_4bit_sleep &pinctrl_mmc1_cd_4bit_sleep>;
+ bus-width = <4>;
+ cap-power-off-card;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ /delete-property/ no-1-8-v;
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+/* Apalis CAN1 */
+&flexcan1 {
+ xceiver-supply = <&reg_can1_supply>;
+ status = "okay";
+};
+
+/* Apalis CAN2 */
+&flexcan2 {
+ xceiver-supply = <&reg_can2_supply>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
new file mode 100644
index 000000000000..601fb7942478
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
@@ -0,0 +1,1844 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ /* Apalis BKL1 */
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bkl_on>;
+ enable-gpios = <&lsio_gpio1 4 GPIO_ACTIVE_HIGH>; /* Apalis BKL1_ON */
+ };
+
+ gpio_fan: gpio-fan {
+ compatible = "gpio-fan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio8>;
+ gpios = <&lsio_gpio3 28 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 3000 1>;
+ };
+
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+ backlight = <&backlight>;
+
+ status = "disabled";
+
+ port {
+ panel_lvds_in: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+
+ pcie_sata_refclk: sata-clock-generator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ pcie_sata_refclk_gate: sata-ref-clock {
+ compatible = "gpio-gate-clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_sata_refclk>;
+ #clock-cells = <0>;
+ clocks = <&pcie_sata_refclk>;
+ enable-gpios = <&lsio_gpio4 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ pcie_wifi_refclk_gate: wifi-ref-clock {
+ compatible = "gpio-gate-clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_wifi_refclk>;
+ #clock-cells = <0>;
+ clocks = <&pcie_sata_refclk_gate>;
+ enable-gpios = <&lsio_gpio2 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * Power management bus used to control LDO1OUT of the
+ * second PMIC PF8100. This is used for controlling voltage levels of
+ * typespecific RGMII signals and Apalis UART2_RTS UART2_CTS.
+ *
+ * IMX_SC_R_BOARD_R1 for 3.3V
+ * IMX_SC_R_BOARD_R2 for 1.8V
+ * IMX_SC_R_BOARD_R3 for 2.5V
+ * Note that for 2.5V operation the pad muxing needs to be changed,
+ * compare with PSW_OVR field of IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD.
+ *
+ * those power domains are mutually exclusive.
+ */
+ reg_ext_rgmii: regulator-ext-rgmii {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_EXT_RGMII (LDO1)";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ power-domains = <&pd IMX_SC_R_BOARD_R1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ reg_module_3v3: regulator-module-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_module_3v3_avdd: regulator-module-3v3-avdd {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3_AUDIO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_module_wifi: regulator-module-wifi {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&lsio_gpio1 28 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi_pdn>;
+ regulator-name = "wifi_pwrdn_fake_regulator";
+ regulator-settling-time-us = <100>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ reg_pcie_switch: regulator-pcie-switch {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio7>;
+ enable-active-high;
+ gpio = <&lsio_gpio3 26 GPIO_ACTIVE_HIGH>;
+ regulator-name = "pcie_switch";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <100000>;
+ };
+
+ reg_vref_1v8: regulator-vref-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "+V1.8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ reg_usb_host_vbus: regulator-usb-host-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh_en>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+
+ /* Apalis USBH_EN */
+ gpio = <&lsio_gpio4 4 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ decoder_boot: decoder_boot@0x84000000 {
+ no-map;
+ reg = <0 0x84000000 0 0x2000000>;
+ };
+ encoder_boot: encoder_boot@0x86000000 {
+ no-map;
+ reg = <0 0x86000000 0 0x400000>;
+ };
+ /*
+ * reserved-memory layout
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+ m4_reserved: m4@0x88000000 {
+ no-map;
+ reg = <0 0x88000000 0 0x8000000>;
+ };
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90200000 0 0x200000>;
+ };
+ decoder_rpc: decoder_rpc@0x92000000 {
+ no-map;
+ reg = <0 0x92000000 0 0x200000>;
+ };
+ encoder_rpc: encoder_rpc@0x92200000 {
+ no-map;
+ reg = <0 0x92200000 0 0x200000>;
+ };
+ dsp_reserved: dsp@0x92400000 {
+ no-map;
+ reg = <0 0x92400000 0 0x2000000>;
+ };
+ encoder_reserved: encoder_reserved@0x94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+ ts_boot: ts_boot@0x95000000 {
+ no-map;
+ reg = <0 0x95000000 0 0x400000>;
+ };
+
+ vdevbuffer: vdevbuffer {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90400000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ /* simple-audio-card,mclk-fs = <1>; */
+ simple-audio-card,name = "apalis-imx8qm-sgtl5000";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ };
+
+ dailink_master: simple-audio-card,codec {
+ clocks = <&mclkout0_lpcg 0>;
+ sound-dai = <&sgtl5000>;
+ };
+ };
+
+ sound_hdmi: sound-hdmi {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "imx-audio-hdmi-tx";
+ audio-cpu = <&sai5>;
+ protocol = <1>;
+ hdmi-out;
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif0>;
+ spdif-in;
+ spdif-out;
+ };
+
+ touchscreen: vf50-touchscreen {
+ compatible = "toradex,vf50-touchscreen";
+ io-channels = <&adc1 2>,<&adc1 1>,
+ <&adc1 0>,<&adc1 3>;
+ xp-gpios = <&lsio_gpio2 4 GPIO_ACTIVE_LOW>;
+ xm-gpios = <&lsio_gpio2 5 GPIO_ACTIVE_HIGH>;
+ yp-gpios = <&lsio_gpio2 17 GPIO_ACTIVE_LOW>;
+ ym-gpios = <&lsio_gpio2 21 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "idle","default";
+ pinctrl-0 = <&pinctrl_touchctrl_idle>, <&pinctrl_touchctrl_gpios>;
+ pinctrl-1 = <&pinctrl_adc1>, <&pinctrl_touchctrl_gpios>;
+ vf50-ts-min-pressure = <200>;
+ /* NOTE: you must remove the pinctrl-adc1 from the adc1
+ node below to use the touchscreen */
+ status = "disabled";
+ };
+
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <&reg_vref_1v8>;
+};
+
+&adc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc1>;
+ vref-supply = <&reg_vref_1v8>;
+};
+
+&asrc0 {
+ fsl,asrc-rate = <48000>;
+};
+
+/* Apalis GLAN */
+&fec1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec1>;
+ pinctrl-1 = <&pinctrl_fec1_sleep>;
+ fsl,magic-packet;
+ fsl,mii-exclusive;
+
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ interrupt-parent = <&lsio_gpio1>;
+ interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <0>;
+ reg = <7>;
+ reset-assert-us = <2>;
+ reset-deassert-us = <2>;
+ reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
+ reset-names = "phy-reset";
+ };
+ };
+};
+
+/* Apalis CAN1 */
+&flexcan1 {
+ /* define the following property to disable CAN-FD mode */
+ /* disable-fd-mode; */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ /* xceiver-supply = <&reg_can_stby>; */
+};
+
+/* Apalis CAN2 */
+&flexcan2 {
+ /* define the following property to disable CAN-FD mode */
+ /* disable-fd-mode; */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ /* xceiver-supply = <&reg_can_stby>; */
+};
+
+/* Apalis CAN3 (optional) */
+&flexcan3 {
+ /* define the following property to disable CAN-FD mode */
+ /* disable-fd-mode; */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ /* xceiver-supply = <&reg_can_stby>; */
+};
+
+
+/* Apalis HDMI1 */
+&hdmi {
+ compatible = "cdn,imx8qm-hdmi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_ctrl>;
+ firmware-name = "imx/hdmi/hdmitxfw.bin";
+ hdmi-ctrl-gpios = <&lsio_gpio1 30 GPIO_ACTIVE_HIGH>;
+ lane-mapping = <0x93>;
+};
+
+&hsio_refa_clk {
+ status = "disabled";
+};
+
+&hsio_refb_clk {
+ status = "disabled";
+};
+
+/* On-module I2C */
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sgtl5000>;
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg 0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ clocks = <&mclkout0_lpcg 0>;
+ clock-names = "mclk";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_module_3v3_avdd>;
+ VDDD-supply = <&reg_vref_1v8>;
+ VDDIO-supply = <&reg_module_3v3>;
+ };
+
+ /* USB3503A */
+ usb3503@8 {
+ compatible = "smsc,usb3503a";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3503a>;
+ connect-gpios = <&lsio_gpio0 31 GPIO_ACTIVE_LOW>;
+ initial-mode = <1>;
+ intn-gpios = <&lsio_gpio1 1 GPIO_ACTIVE_LOW>;
+ refclk-frequency = <25000000>;
+ reg = <0x08>;
+ reset-gpios = <&lsio_gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+/* Apalis I2C1 */
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+};
+
+/* Apalis I2C3 (CAM) */
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cam1_gpios>, <&pinctrl_dap1_gpios>,
+ <&pinctrl_esai0_gpios>, <&pinctrl_fec2_gpios>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>, <&pinctrl_gpio_keys>,
+ <&pinctrl_gpio_usbh_oc_n>, <&pinctrl_lpuart1ctrl>,
+ <&pinctrl_lvds0_i2c0_gpio>, <&pinctrl_lvds1_i2c0_gpios>,
+ <&pinctrl_mipi_dsi_0_1_en>, <&pinctrl_mipi_dsi1_gpios>,
+ <&pinctrl_mlb_gpios>, <&pinctrl_qspi1a_gpios>,
+ <&pinctrl_sata1_act>, <&pinctrl_sim0_gpios>,
+ <&pinctrl_usdhc1_gpios>;
+
+ apalis-imx8qm {
+ /* Apalis AN1_ADC */
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <
+ /* Apalis AN1_ADC0 */
+ IMX8QM_ADC_IN0_DMA_ADC0_IN0 0xc0000060
+ /* Apalis AN1_ADC1 */
+ IMX8QM_ADC_IN1_DMA_ADC0_IN1 0xc0000060
+ /* Apalis AN1_ADC2 */
+ IMX8QM_ADC_IN2_DMA_ADC0_IN2 0xc0000060
+ /* Apalis AN1_TSWIP_ADC3 */
+ IMX8QM_ADC_IN3_DMA_ADC0_IN3 0xc0000060
+ >;
+ };
+
+ /* Apalis AN1_TS */
+ pinctrl_adc1: adc1grp {
+ fsl,pins = <
+ /* Apalis AN1_TSPX */
+ IMX8QM_ADC_IN4_DMA_ADC1_IN0 0xc0000060
+ /* Apalis AN1_TSMX */
+ IMX8QM_ADC_IN5_DMA_ADC1_IN1 0xc0000060
+ /* Apalis AN1_TSPY */
+ IMX8QM_ADC_IN6_DMA_ADC1_IN2 0xc0000060
+ /* Apalis AN1_TSMY */
+ IMX8QM_ADC_IN7_DMA_ADC1_IN3 0xc0000060
+ >;
+ };
+
+ /* Apalis BKL_ON */
+ pinctrl_gpio_bkl_on: gpio-bkl-on {
+ fsl,pins = <
+ IMX8QM_LVDS0_GPIO00_LSIO_GPIO1_IO04 0x00000021
+ >;
+ };
+
+ /* Apalis BKL1_PWM */
+ pinctrl_pwm_bkl: pwmbklgrp {
+ fsl,pins = <
+ IMX8QM_LVDS1_GPIO00_LVDS1_PWM0_OUT 0x00000020
+ >;
+ };
+
+ /* Apalis CAM1 */
+ pinctrl_cam1_gpios: cam1gpiosgrp {
+ fsl,pins = <
+ /* Apalis CAM1_D7 */
+ IMX8QM_MIPI_DSI1_I2C0_SCL_LSIO_GPIO1_IO20 0x00000021
+ /* Apalis CAM1_D6 */
+ IMX8QM_MIPI_DSI1_I2C0_SDA_LSIO_GPIO1_IO21 0x00000021
+ /* Apalis CAM1_D5 */
+ IMX8QM_ESAI0_TX0_LSIO_GPIO2_IO26 0x00000021
+ /* Apalis CAM1_D4 */
+ IMX8QM_ESAI0_TX1_LSIO_GPIO2_IO27 0x00000021
+ /* Apalis CAM1_D3 */
+ IMX8QM_ESAI0_TX2_RX3_LSIO_GPIO2_IO28 0x00000021
+ /* Apalis CAM1_D2 */
+ IMX8QM_ESAI0_TX3_RX2_LSIO_GPIO2_IO29 0x00000021
+ /* Apalis CAM1_D1 */
+ IMX8QM_ESAI0_TX4_RX1_LSIO_GPIO2_IO30 0x00000021
+ /* Apalis CAM1_D0 */
+ IMX8QM_ESAI0_TX5_RX0_LSIO_GPIO2_IO31 0x00000021
+ /* Apalis CAM1_PCLK */
+ IMX8QM_MCLK_IN0_LSIO_GPIO3_IO00 0x00000021
+ /* Apalis CAM1_MCLK */
+ IMX8QM_SPI3_SDO_LSIO_GPIO2_IO18 0x00000021
+ /* Apalis CAM1_VSYNC */
+ IMX8QM_ESAI0_SCKR_LSIO_GPIO2_IO24 0x00000021
+ /* Apalis CAM1_HSYNC */
+ IMX8QM_ESAI0_SCKT_LSIO_GPIO2_IO25 0x00000021
+ >;
+ };
+
+ /* Apalis CAN1 */
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x21
+ IMX8QM_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x21
+ >;
+ };
+
+ /* Apalis CAN2 */
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x21
+ IMX8QM_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x21
+ >;
+ };
+
+ /* Apalis CAN3 (optional) */
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN2_TX_DMA_FLEXCAN2_TX 0x21
+ IMX8QM_FLEXCAN2_RX_DMA_FLEXCAN2_RX 0x21
+ >;
+ };
+
+ /* Apalis DAP1 */
+ pinctrl_dap1_gpios: dap1gpiosgrp {
+ fsl,pins = <
+ /* Apalis DAP1_MCLK */
+ IMX8QM_SPI3_SDI_LSIO_GPIO2_IO19 0x00000021
+ /* Apalis DAP1_D_OUT */
+ IMX8QM_SAI1_RXC_LSIO_GPIO3_IO12 0x00000021
+ /* Apalis DAP1_RESET */
+ IMX8QM_ESAI1_SCKT_LSIO_GPIO2_IO07 0x00000021
+ /* Apalis DAP1_BIT_CLK */
+ IMX8QM_SPI0_CS1_LSIO_GPIO3_IO06 0x00000021
+ /* Apalis DAP1_D_IN */
+ IMX8QM_SAI1_RXFS_LSIO_GPIO3_IO14 0x00000021
+ /* Apalis DAP1_SYNC */
+ IMX8QM_SPI2_CS1_LSIO_GPIO3_IO11 0x00000021
+ /* On-module Wi-Fi_I2S_EN# */
+ IMX8QM_ESAI1_TX5_RX0_LSIO_GPIO2_IO13 0x00000021
+ >;
+ };
+
+ /* Apalis GPIO1 */
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ IMX8QM_M40_GPIO0_00_LSIO_GPIO0_IO08 0x06000021
+ >;
+ };
+
+ /* Apalis GPIO2 */
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <
+ IMX8QM_M40_GPIO0_01_LSIO_GPIO0_IO09 0x06000021
+ >;
+ };
+
+ /* Apalis GPIO3 */
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ IMX8QM_M41_GPIO0_00_LSIO_GPIO0_IO12 0x06000021
+ >;
+ };
+
+ /* Apalis GPIO4 */
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ IMX8QM_M41_GPIO0_01_LSIO_GPIO0_IO13 0x06000021
+ >;
+ };
+
+ /* Apalis GPIO5 */
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN2_RX_LSIO_GPIO4_IO01 0x06000021
+ >;
+ };
+
+ /* Apalis GPIO6 */
+ pinctrl_gpio6: gpio6grp {
+ fsl,pins = <
+ IMX8QM_FLEXCAN2_TX_LSIO_GPIO4_IO02 0x00000021
+ >;
+ };
+
+ /* Apalis GPIO7 */
+ pinctrl_gpio7: gpio7grp {
+ fsl,pins = <
+ IMX8QM_MLB_SIG_LSIO_GPIO3_IO26 0x00000021
+ >;
+ };
+
+ /* Apalis GPIO8 */
+ pinctrl_gpio8: gpio8grp {
+ fsl,pins = <
+ IMX8QM_MLB_DATA_LSIO_GPIO3_IO28 0x00000021
+ >;
+ };
+
+ /* Apalis I2C1 */
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ IMX8QM_GPT1_CLK_DMA_I2C2_SCL 0x04000020
+ IMX8QM_GPT1_CAPTURE_DMA_I2C2_SDA 0x04000020
+ >;
+ };
+
+ /* Apalis I2C3 (CAM) */
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ IMX8QM_SIM0_PD_DMA_I2C3_SCL 0x04000020
+ IMX8QM_SIM0_POWER_EN_DMA_I2C3_SDA 0x04000020
+ >;
+ };
+
+ /* Apalis LCD1_G1+2 */
+ pinctrl_esai0_gpios: esai0gpiosgrp {
+ fsl,pins = <
+ /* Apalis LCD1_G1 */
+ IMX8QM_ESAI0_FSR_LSIO_GPIO2_IO22 0x00000021
+ /* Apalis LCD1_G2 */
+ IMX8QM_ESAI0_FST_LSIO_GPIO2_IO23 0x00000021
+ >;
+ };
+
+ /* Apalis LCD1_G6+7 */
+ pinctrl_lvds1_i2c0_gpios: lvds1i2c0gpiosgrp {
+ fsl,pins = <
+ /* Apalis LCD1_G6 */
+ IMX8QM_LVDS1_I2C0_SCL_LSIO_GPIO1_IO12 0x00000021
+ /* Apalis LCD1_G7 */
+ IMX8QM_LVDS1_I2C0_SDA_LSIO_GPIO1_IO13 0x00000021
+ >;
+ };
+
+ /* Apalis LCD1_ */
+ pinctrl_fec2_gpios: fec2gpiosgrp {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0
+ /* Apalis LCD1_R1 */
+ IMX8QM_ENET1_MDC_LSIO_GPIO4_IO18 0x00000021
+ /* Apalis LCD1_R0 */
+ IMX8QM_ENET1_MDIO_LSIO_GPIO4_IO17 0x00000021
+ /* Apalis LCD1_G0 */
+ IMX8QM_ENET1_REFCLK_125M_25M_LSIO_GPIO4_IO16 0x00000021
+ /* Apalis LCD1_R7 */
+ IMX8QM_ENET1_RGMII_RX_CTL_LSIO_GPIO6_IO17 0x00000021
+ /* Apalis LCD1_DE */
+ IMX8QM_ENET1_RGMII_RXD0_LSIO_GPIO6_IO18 0x00000021
+ /* Apalis LCD1_HSYNC */
+ IMX8QM_ENET1_RGMII_RXD1_LSIO_GPIO6_IO19 0x00000021
+ /* Apalis LCD1_VSYNC */
+ IMX8QM_ENET1_RGMII_RXD2_LSIO_GPIO6_IO20 0x00000021
+ /* Apalis LCD1_PCLK */
+ IMX8QM_ENET1_RGMII_RXD3_LSIO_GPIO6_IO21 0x00000021
+ /* Apalis LCD1_R6 */
+ IMX8QM_ENET1_RGMII_TX_CTL_LSIO_GPIO6_IO11 0x00000021
+ /* Apalis LCD1_R5 */
+ IMX8QM_ENET1_RGMII_TXC_LSIO_GPIO6_IO10 0x00000021
+ /* Apalis LCD1_R4 */
+ IMX8QM_ENET1_RGMII_TXD0_LSIO_GPIO6_IO12 0x00000021
+ /* Apalis LCD1_R3 */
+ IMX8QM_ENET1_RGMII_TXD1_LSIO_GPIO6_IO13 0x00000021
+ /* Apalis LCD1_R2 */
+ IMX8QM_ENET1_RGMII_TXD2_LSIO_GPIO6_IO14 0x00000021
+ >;
+ };
+
+ /* Apalis LCD1_ */
+ pinctrl_qspi1a_gpios: qspi1agpiosgrp {
+ fsl,pins = <
+ /* Apalis LCD1_B0 */
+ IMX8QM_QSPI1A_DATA0_LSIO_GPIO4_IO26 0x00000021
+ /* Apalis LCD1_B1 */
+ IMX8QM_QSPI1A_DATA1_LSIO_GPIO4_IO25 0x00000021
+ /* Apalis LCD1_B2 */
+ IMX8QM_QSPI1A_DATA2_LSIO_GPIO4_IO24 0x00000021
+ /* Apalis LCD1_B3 */
+ IMX8QM_QSPI1A_DATA3_LSIO_GPIO4_IO23 0x00000021
+ /* Apalis LCD1_B5 */
+ IMX8QM_QSPI1A_DQS_LSIO_GPIO4_IO22 0x00000021
+ /* Apalis LCD1_B7 */
+ IMX8QM_QSPI1A_SCLK_LSIO_GPIO4_IO21 0x00000021
+ /* Apalis LCD1_B4 */
+ IMX8QM_QSPI1A_SS0_B_LSIO_GPIO4_IO19 0x00000021
+ /* Apalis LCD1_B6 */
+ IMX8QM_QSPI1A_SS1_B_LSIO_GPIO4_IO20 0x00000021
+ >;
+ };
+
+ /* Apalis LCD1_ */
+ pinctrl_sim0_gpios: sim0gpiosgrp {
+ fsl,pins = <
+ /* Apalis LCD1_G5 */
+ IMX8QM_SIM0_CLK_LSIO_GPIO0_IO00 0x00000021
+ /* Apalis LCD1_G3 */
+ IMX8QM_SIM0_GPIO0_00_LSIO_GPIO0_IO05 0x00000021
+ /* Apalis TS_5 */
+ IMX8QM_SIM0_IO_LSIO_GPIO0_IO02 0x00000021
+ /* Apalis LCD1_G4 */
+ IMX8QM_SIM0_RST_LSIO_GPIO0_IO01 0x00000021
+ >;
+ };
+
+ /* Apalis MMC1_CD# */
+ pinctrl_mmc1_cd: mmc1cdgrp {
+ fsl,pins = <
+ IMX8QM_ESAI1_TX1_LSIO_GPIO2_IO09 0x00000021
+ >;
+ };
+
+ /* Apalis MMC1 */
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
+ IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
+ IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
+ IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
+ IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
+ IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
+ IMX8QM_USDHC1_DATA4_CONN_USDHC1_DATA4 0x00000021
+ IMX8QM_USDHC1_DATA5_CONN_USDHC1_DATA5 0x00000021
+ IMX8QM_USDHC1_DATA6_CONN_USDHC1_DATA6 0x00000021
+ IMX8QM_USDHC1_DATA7_CONN_USDHC1_DATA7 0x00000021
+ /* On-module PMIC use */
+ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ IMX8QM_USDHC1_DATA4_CONN_USDHC1_DATA4 0x00000020
+ IMX8QM_USDHC1_DATA5_CONN_USDHC1_DATA5 0x00000020
+ IMX8QM_USDHC1_DATA6_CONN_USDHC1_DATA6 0x00000020
+ IMX8QM_USDHC1_DATA7_CONN_USDHC1_DATA7 0x00000020
+ /* On-module PMIC use */
+ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040
+ IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020
+ IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020
+ IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020
+ IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020
+ IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020
+ IMX8QM_USDHC1_DATA4_CONN_USDHC1_DATA4 0x00000020
+ IMX8QM_USDHC1_DATA5_CONN_USDHC1_DATA5 0x00000020
+ IMX8QM_USDHC1_DATA6_CONN_USDHC1_DATA6 0x00000020
+ IMX8QM_USDHC1_DATA7_CONN_USDHC1_DATA7 0x00000020
+ /* On-module PMIC use */
+ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020
+ >;
+ };
+
+ /* Apalis PWM1 */
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ IMX8QM_GPT1_COMPARE_LSIO_PWM2_OUT 0x00000020
+ >;
+ };
+
+ /* Apalis PWM2 */
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ IMX8QM_GPT0_COMPARE_LSIO_PWM3_OUT 0x00000020
+ >;
+ };
+
+ /* Apalis PWM3 */
+ pinctrl_pwm0: pwm0grp {
+ fsl,pins = <
+ IMX8QM_UART0_RTS_B_LSIO_PWM0_OUT 0x00000020
+ >;
+ };
+
+ /* Apalis PWM4 */
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ IMX8QM_UART0_CTS_B_LSIO_PWM1_OUT 0x00000020
+ >;
+ };
+
+ /* Apalis SATA1_ACT# */
+ pinctrl_sata1_act: sata1actgrp {
+ fsl,pins = <
+ IMX8QM_ESAI1_TX0_LSIO_GPIO2_IO08 0x00000021
+ >;
+ };
+
+ /* Apalis SD1_CD# */
+ pinctrl_sd1_cd: sd1cdgrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000021
+ >;
+ };
+
+ /* Apalis SD1 */
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ IMX8QM_USDHC2_CLK_CONN_USDHC2_CLK 0x06000041
+ IMX8QM_USDHC2_CMD_CONN_USDHC2_CMD 0x00000021
+ IMX8QM_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000021
+ IMX8QM_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000021
+ IMX8QM_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000021
+ IMX8QM_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000021
+ /* On-module PMIC use */
+ IMX8QM_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_touchctrl_idle: touchctrl_idle {
+ fsl,pins = <
+ IMX8QM_ADC_IN4_LSIO_GPIO3_IO22 0x00000021
+ IMX8QM_ADC_IN5_LSIO_GPIO3_IO23 0x00000021
+ IMX8QM_ADC_IN6_LSIO_GPIO3_IO24 0x00000021
+ IMX8QM_ADC_IN7_LSIO_GPIO3_IO25 0x00000021
+ >;
+ };
+
+ pinctrl_touchctrl_gpios: touchctrl_gpios {
+ fsl,pins = <
+ IMX8QM_ESAI1_FSR_LSIO_GPIO2_IO04 0x00000021
+ IMX8QM_ESAI1_FST_LSIO_GPIO2_IO05 0x00000041
+ IMX8QM_SPI3_SCK_LSIO_GPIO2_IO17 0x00000021
+ IMX8QM_SPI3_CS1_LSIO_GPIO2_IO21 0x00000041
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ IMX8QM_USDHC2_CLK_CONN_USDHC2_CLK 0x06000041
+ IMX8QM_USDHC2_CMD_CONN_USDHC2_CMD 0x00000021
+ IMX8QM_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000021
+ IMX8QM_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000021
+ IMX8QM_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000021
+ IMX8QM_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000021
+ /* On-module PMIC use */
+ IMX8QM_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ IMX8QM_USDHC2_CLK_CONN_USDHC2_CLK 0x06000041
+ IMX8QM_USDHC2_CMD_CONN_USDHC2_CMD 0x00000021
+ IMX8QM_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000021
+ IMX8QM_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000021
+ IMX8QM_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000021
+ IMX8QM_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000021
+ /* On-module PMIC use */
+ IMX8QM_USDHC2_VSELECT_CONN_USDHC2_VSELECT 0x00000021
+ >;
+ };
+
+ /* Apalis SPDIF */
+ pinctrl_spdif0: spdif0grp {
+ fsl,pins = <
+ IMX8QM_SPDIF0_TX_AUD_SPDIF0_TX 0xc6000040
+ IMX8QM_SPDIF0_RX_AUD_SPDIF0_RX 0xc6000040
+ >;
+ };
+
+ /* Apalis SPI1 */
+ pinctrl_lpspi0: lpspi0grp {
+ fsl,pins = <
+ IMX8QM_SPI0_SCK_DMA_SPI0_SCK 0x0600004c
+ IMX8QM_SPI0_SDO_DMA_SPI0_SDO 0x0600004c
+ IMX8QM_SPI0_SDI_DMA_SPI0_SDI 0x0600004c
+ IMX8QM_SPI0_CS0_LSIO_GPIO3_IO05 0x0600004c
+ >;
+ };
+
+ /* Apalis SPI2 */
+ pinctrl_lpspi2: lpspi2grp {
+ fsl,pins = <
+ IMX8QM_SPI2_SCK_DMA_SPI2_SCK 0x0600004c
+ IMX8QM_SPI2_SDO_DMA_SPI2_SDO 0x0600004c
+ IMX8QM_SPI2_SDI_DMA_SPI2_SDI 0x0600004c
+ IMX8QM_SPI2_CS0_LSIO_GPIO3_IO10 0x0600004c
+ >;
+ };
+
+ /* Apalis TS_1 */
+ pinctrl_mlb_gpios: mlbgpiosgrp {
+ fsl,pins = <
+ IMX8QM_MLB_CLK_LSIO_GPIO3_IO27 0x00000021
+ >;
+ };
+
+ /* Apalis TS_2 */
+ pinctrl_lvds0_i2c0_gpio: lvds0i2c0gpio {
+ fsl,pins = <
+ IMX8QM_LVDS0_I2C0_SCL_LSIO_GPIO1_IO06 0x00000021
+ >;
+ };
+
+ /* Apalis TS_3 */
+ pinctrl_mipi_dsi_0_1_en: mipi_dsi_0_1_en {
+ fsl,pins = <
+ IMX8QM_LVDS0_I2C0_SDA_LSIO_GPIO1_IO07 0x00000021
+ >;
+ };
+
+ /* Apalis TS_4 */
+ pinctrl_mipi_dsi1_gpios: mipidsi1gpiosgrp {
+ fsl,pins = <
+ IMX8QM_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO22 0x00000021
+ >;
+ };
+
+ /* Apalis TS_6 */
+ pinctrl_usdhc1_gpios: usdhc1gpiosgrp {
+ fsl,pins = <
+ IMX8QM_USDHC1_STROBE_LSIO_GPIO5_IO23 0x00000021
+ >;
+ };
+
+ /* Apalis UART1 */
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <
+ IMX8QM_UART1_RX_DMA_UART1_RX 0x06000020
+ IMX8QM_UART1_TX_DMA_UART1_TX 0x06000020
+ IMX8QM_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020
+ IMX8QM_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020
+ >;
+ };
+
+ /* Apalis UART1_ */
+ pinctrl_lpuart1ctrl: lpuart1ctrlgrp {
+ fsl,pins = <
+ /* Apalis UART1_DTR */
+ IMX8QM_M40_I2C0_SCL_LSIO_GPIO0_IO06 0x00000021
+ /* Apalis UART1_DSR */
+ IMX8QM_M40_I2C0_SDA_LSIO_GPIO0_IO07 0x00000021
+ /* Apalis UART1_DCD */
+ IMX8QM_M41_I2C0_SCL_LSIO_GPIO0_IO10 0x00000021
+ /* Apalis UART1_RI */
+ IMX8QM_M41_I2C0_SDA_LSIO_GPIO0_IO11 0x00000021
+ >;
+ };
+
+ /* Apalis UART2 */
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ IMX8QM_LVDS1_I2C1_SCL_DMA_UART3_TX 0x06000020
+ IMX8QM_LVDS1_I2C1_SDA_DMA_UART3_RX 0x06000020
+ IMX8QM_ENET1_RGMII_TXD3_DMA_UART3_RTS_B 0x06000020
+ IMX8QM_ENET1_RGMII_RXC_DMA_UART3_CTS_B 0x06000020
+ >;
+ };
+
+ /* Apalis UART3 */
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ IMX8QM_UART0_RX_DMA_UART0_RX 0x06000020
+ IMX8QM_UART0_TX_DMA_UART0_TX 0x06000020
+ >;
+ };
+
+ /* Apalis UART4 */
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ IMX8QM_LVDS0_I2C1_SCL_DMA_UART2_TX 0x06000020
+ IMX8QM_LVDS0_I2C1_SDA_DMA_UART2_RX 0x06000020
+ >;
+ };
+
+ /* Apalis USBH_EN */
+ pinctrl_usbh_en: usbhen {
+ fsl,pins = <
+ IMX8QM_USB_SS3_TC1_LSIO_GPIO4_IO04 0x00000021
+ >;
+ };
+
+ /* Apalis USBH_OC# */
+ pinctrl_gpio_usbh_oc_n: gpiousbhocn {
+ fsl,pins = <
+ IMX8QM_USB_SS3_TC3_LSIO_GPIO4_IO06 0x04000021
+ >;
+ };
+
+ /* Apalis USBO1 */
+ pinctrl_usbotg1: usbotg1 {
+ fsl,pins = <
+ /* Apalis USBO1_EN */
+ IMX8QM_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021
+ /* Apalis USBO1_OC# */
+ IMX8QM_USB_SS3_TC2_CONN_USB_OTG1_OC 0x04000021
+ >;
+ };
+
+ /* Apalis WAKE1_MICO */
+ pinctrl_gpio_keys: gpio-keys {
+ fsl,pins = <
+ IMX8QM_SPI3_CS0_LSIO_GPIO2_IO20 0x06700021
+ >;
+ };
+
+ /* On-module eMMC */
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041
+ IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040
+ IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020
+ >;
+ };
+
+ /* On-module Gigabit Ethernet PHY Micrel KSZ9031 for Apalis GLAN */
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0 /* Use pads in 3.3V mode */
+ IMX8QM_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ IMX8QM_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ IMX8QM_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x06000020
+ IMX8QM_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x06000020
+ IMX8QM_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x06000020
+ IMX8QM_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x06000020
+ IMX8QM_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x06000020
+ IMX8QM_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x06000020
+ IMX8QM_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x06000020
+ IMX8QM_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x06000020
+ IMX8QM_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x06000020
+ IMX8QM_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x06000020
+ IMX8QM_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x06000020
+ IMX8QM_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x06000020
+ IMX8QM_ENET0_REFCLK_125M_25M_CONN_ENET0_REFCLK_125M_25M 0x06000020
+ /* On-module ETH_RESET# */
+ IMX8QM_LVDS1_GPIO01_LSIO_GPIO1_IO11 0x06000020
+ /* On-module ETH_INT# */
+ IMX8QM_MIPI_CSI1_MCLK_OUT_LSIO_GPIO1_IO29 0x04000060
+ >;
+ };
+
+ pinctrl_fec1_sleep: fec1-sleepgrp {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0
+ IMX8QM_ENET0_MDC_LSIO_GPIO4_IO14 0x04000040
+ IMX8QM_ENET0_MDIO_LSIO_GPIO4_IO13 0x04000040
+ IMX8QM_ENET0_RGMII_TX_CTL_LSIO_GPIO5_IO31 0x04000040
+ IMX8QM_ENET0_RGMII_TXC_LSIO_GPIO5_IO30 0x04000040
+ IMX8QM_ENET0_RGMII_TXD0_LSIO_GPIO6_IO00 0x04000040
+ IMX8QM_ENET0_RGMII_TXD1_LSIO_GPIO6_IO01 0x04000040
+ IMX8QM_ENET0_RGMII_TXD2_LSIO_GPIO6_IO02 0x04000040
+ IMX8QM_ENET0_RGMII_TXD3_LSIO_GPIO6_IO03 0x04000040
+ IMX8QM_ENET0_RGMII_RXC_LSIO_GPIO6_IO04 0x04000040
+ IMX8QM_ENET0_RGMII_RX_CTL_LSIO_GPIO6_IO05 0x04000040
+ IMX8QM_ENET0_RGMII_RXD0_LSIO_GPIO6_IO06 0x04000040
+ IMX8QM_ENET0_RGMII_RXD1_LSIO_GPIO6_IO07 0x04000040
+ IMX8QM_ENET0_RGMII_RXD2_LSIO_GPIO6_IO08 0x04000040
+ IMX8QM_ENET0_RGMII_RXD3_LSIO_GPIO6_IO09 0x04000040
+ IMX8QM_ENET0_REFCLK_125M_25M_LSIO_GPIO4_IO15 0x04000040
+ IMX8QM_LVDS1_GPIO01_LSIO_GPIO1_IO11 0x06000020
+ IMX8QM_MIPI_CSI1_MCLK_OUT_LSIO_GPIO1_IO29 0x04000040
+ >;
+ };
+
+ /* On-module HDMI_CTRL */
+ pinctrl_hdmi_ctrl: hdmictrlgrp {
+ fsl,pins = <
+ IMX8QM_MIPI_CSI1_GPIO0_00_LSIO_GPIO1_IO30 0x00000061
+ >;
+ };
+
+ /* On-module I2C */
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ IMX8QM_GPT0_CLK_DMA_I2C1_SCL 0x04000020
+ IMX8QM_GPT0_CAPTURE_DMA_I2C1_SDA 0x04000020
+ >;
+ };
+
+ /* On-module I2S SGTL5000 for Apalis Analogue Audio */
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ IMX8QM_SAI1_TXD_AUD_SAI1_TXD 0xc600006c
+ IMX8QM_SAI1_RXD_AUD_SAI1_RXD 0xc600004c
+ IMX8QM_SAI1_TXC_AUD_SAI1_TXC 0xc600004c
+ IMX8QM_SAI1_TXFS_AUD_SAI1_TXFS 0xc600004c
+ >;
+ };
+
+ /* On-module I2S SGTL5000 SYS_MCLK */
+ pinctrl_sgtl5000: sgtl5000grp {
+ fsl,pins = <
+ IMX8QM_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0xc600004c
+ >;
+ };
+
+ /* On-module PCIe_CLK_EN1 */
+ pinctrl_pcie_sata_refclk: pciesatarefclkgrp {
+ fsl,pins = <
+ IMX8QM_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021
+ >;
+ };
+
+ /* On-module PCIe_CLK_EN2 */
+ pinctrl_pcie_wifi_refclk: pciewifirefclkgrp {
+ fsl,pins = <
+ IMX8QM_ESAI1_TX3_RX2_LSIO_GPIO2_IO11 0x00000021
+ >;
+ };
+
+ /* On-module PCIe_Wi-Fi */
+ pinctrl_pcieb: pciebgrp {
+ fsl,pins = <
+ IMX8QM_PCIE_CTRL1_CLKREQ_B_LSIO_GPIO4_IO30 0x00000021
+ IMX8QM_PCIE_CTRL1_WAKE_B_LSIO_GPIO4_IO31 0x00000021
+ IMX8QM_PCIE_CTRL1_PERST_B_LSIO_GPIO5_IO00 0x00000021
+ >;
+ };
+
+ /* On-module RESET_MOCI#_DRV */
+ pinctrl_reset_moci: resetmocigrp {
+ fsl,pins = <
+ IMX8QM_SCU_GPIO0_02_LSIO_GPIO0_IO30 0x00000021
+ >;
+ };
+
+ /* On-module USB HSIC HUB */
+ pinctrl_usb3503a: usb3503agrp {
+ fsl,pins = <
+ /* On-module HSIC_HUB_CONNECT */
+ IMX8QM_SCU_GPIO0_03_LSIO_GPIO0_IO31 0x00000041
+ /* On-module HSIC_INT_N */
+ IMX8QM_SCU_GPIO0_05_LSIO_GPIO1_IO01 0x00000021
+ /* On-module HSIC_RESET_N */
+ IMX8QM_SCU_GPIO0_06_LSIO_GPIO1_IO02 0x00000041
+ >;
+ };
+
+ /* On-module USB HSIC HUB (idle) */
+ pinctrl_usb_hsic_idle: usbh1_1 {
+ fsl,pins = <
+ IMX8QM_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA 0x000000cf
+ IMX8QM_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE 0x000000cf
+ >;
+ };
+
+ /* On-module USB HSIC HUB (active) */
+ pinctrl_usb_hsic_active: usbh1_2 {
+ fsl,pins = <
+ IMX8QM_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA 0x000000cf
+ IMX8QM_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE 0x000000ff
+ >;
+ };
+
+ /* On-module Wi-Fi */
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ /* On-module Wi-Fi_SUSCLK_32k */
+ IMX8QM_SCU_GPIO0_07_SCU_DSC_RTC_CLOCK_OUTPUT_32K 0x06000021
+ /* On-module Wi-Fi_PCIE_W_DISABLE */
+ IMX8QM_MIPI_CSI0_MCLK_OUT_LSIO_GPIO1_IO24 0x06000021
+ >;
+ };
+
+ pinctrl_wifi_pdn: wifipdngrp {
+ fsl,pins = <
+ /* On-module Wi-Fi_POWER_DOWN */
+ IMX8QM_MIPI_CSI0_GPIO0_01_LSIO_GPIO1_IO28 0x06000021
+ >;
+ };
+ };
+};
+
+&jpegdec {
+ status = "okay";
+};
+
+&jpegenc {
+ status = "okay";
+};
+
+&ldb2_phy {
+ status = "disabled";
+};
+
+&ldb2 {
+ status = "disabled";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_lvds_in>;
+ };
+ };
+ };
+};
+
+/* Apalis SPI1 */
+&lpspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&lsio_gpio3 5 GPIO_ACTIVE_LOW>;
+
+ spidev0: spi@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <4000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&lpspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&lsio_gpio3 10 GPIO_ACTIVE_LOW>;
+
+ spidev1: spi@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <4000000>;
+ };
+};
+
+/* Apalis UART3 */
+&lpuart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+};
+
+/* Apalis UART1 */
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+};
+
+/* Apalis UART4 */
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ dma-names = "","";
+};
+
+/* Apalis UART2 */
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+};
+
+&lsio_gpio0 {
+ gpio-line-names = "MXM3_279",
+ "MXM3_277",
+ "MXM3_135",
+ "MXM3_203",
+ "MXM3_201",
+ "MXM3_275",
+ "MXM3_110",
+ "MXM3_120",
+ "MXM3_1/GPIO1",
+ "MXM3_3/GPIO2",
+ "MXM3_124",
+ "MXM3_122",
+ "MXM3_5/GPIO3",
+ "MXM3_7/GPIO4",
+ "",
+ "",
+ "MXM3_4",
+ "MXM3_211",
+ "MXM3_209",
+ "MXM3_2",
+ "MXM3_136",
+ "MXM3_134",
+ "MXM3_6",
+ "MXM3_8",
+ "MXM3_112",
+ "MXM3_118",
+ "MXM3_114",
+ "MXM3_116";
+};
+
+&lsio_gpio1 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "MXM3_286",
+ "",
+ "MXM3_87",
+ "MXM3_99",
+ "MXM3_138",
+ "MXM3_140",
+ "MXM3_239",
+ "",
+ "MXM3_281",
+ "MXM3_283",
+ "MXM3_126",
+ "MXM3_132",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_173",
+ "MXM3_175",
+ "MXM3_123";
+};
+
+&lsio_gpio2 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_198",
+ "MXM3_35",
+ "MXM3_164",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_217",
+ "MXM3_215",
+ "",
+ "",
+ "MXM3_193",
+ "MXM3_194",
+ "MXM3_37",
+ "",
+ "MXM3_271",
+ "MXM3_273",
+ "MXM3_195",
+ "MXM3_197",
+ "MXM3_177",
+ "MXM3_179",
+ "MXM3_181",
+ "MXM3_183",
+ "MXM3_185",
+ "MXM3_187";
+
+ /*
+ * Add GPIO2_20 as a wakeup source:
+ * Pin: 101 SC_P_SPI3_CS0 (MXM3_37/WAKE1_MICO)
+ * Type: 5 SC_PAD_WAKEUP_FALL_EDGE
+ * Line: 20
+ */
+ pad-wakeup = <IMX8QM_SPI3_CS0 5 20>;
+ pad-wakeup-num = <1>;
+};
+
+&lsio_gpio3 {
+ gpio-line-names = "MXM3_191",
+ "",
+ "MXM3_221",
+ "MXM3_225",
+ "MXM3_223",
+ "MXM3_227",
+ "MXM3_200",
+ "MXM3_235",
+ "MXM3_231",
+ "MXM3_229",
+ "MXM3_233",
+ "MXM3_204",
+ "MXM3_196",
+ "",
+ "MXM3_202",
+ "",
+ "",
+ "",
+ "MXM3_305",
+ "MXM3_307",
+ "MXM3_309",
+ "MXM3_311",
+ "MXM3_315",
+ "MXM3_317",
+ "MXM3_319",
+ "MXM3_321",
+ "MXM3_15/GPIO7",
+ "MXM3_63",
+ "MXM3_17/GPIO8",
+ "MXM3_12",
+ "MXM3_14",
+ "MXM3_16";
+};
+
+&lsio_gpio4 {
+ gpio-line-names = "MXM3_18",
+ "MXM3_11/GPIO5",
+ "MXM3_13/GPIO6",
+ "MXM3_274",
+ "MXM3_84",
+ "MXM3_262",
+ "MXM3_96",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_190",
+ "",
+ "",
+ "",
+ "MXM3_269",
+ "MXM3_251",
+ "MXM3_253",
+ "MXM3_295",
+ "MXM3_299",
+ "MXM3_301",
+ "MXM3_297",
+ "MXM3_293",
+ "MXM3_291",
+ "MXM3_289",
+ "MXM3_287";
+};
+
+&lsio_gpio5 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_150",
+ "MXM3_160",
+ "MXM3_162",
+ "MXM3_144",
+ "MXM3_146",
+ "MXM3_148",
+ "MXM3_152",
+ "MXM3_156",
+ "MXM3_158",
+ "MXM3_159",
+ "MXM3_184",
+ "MXM3_180",
+ "MXM3_186",
+ "MXM3_188",
+ "MXM3_176",
+ "MXM3_178";
+};
+
+&lsio_gpio6 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_261",
+ "MXM3_263",
+ "MXM3_259",
+ "MXM3_257",
+ "MXM3_255",
+ "MXM3_128",
+ "MXM3_130",
+ "MXM3_265",
+ "MXM3_249",
+ "MXM3_247",
+ "MXM3_245",
+ "MXM3_243";
+};
+
+&mu_m0{
+ interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mu1_m0{
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mu2_m0{
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+&mu3_m0{
+ interrupts = <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
+
+/* Apalis PCIE1 */
+&pciea {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
+ clocks = <&pciea_lpcg 0>,
+ <&pciea_lpcg 1>,
+ <&pciea_lpcg 2>,
+ <&phyx2_lpcg 0>,
+ <&phyx2_crr0_lpcg 0>,
+ <&pciea_crr2_lpcg 0>,
+ <&misc_crr5_lpcg 0>,
+ <&pcie_sata_refclk_gate>;
+ clock-names = "pcie", "pcie_bus", "pcie_inbound_axi",
+ "pcie_phy", "phy_per", "pcie_per", "misc_per",
+ "pcie_ext";
+
+ ext_osc = <1>;
+ fsl,max-link-speed = <1>;
+ reset-gpio = <&lsio_gpio0 30 GPIO_ACTIVE_LOW>;
+ vpcie-supply = <&reg_pcie_switch>;
+};
+
+/* On-module Wi-Fi */
+&pcieb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb &pinctrl_wifi>;
+ clocks = <&pcieb_lpcg 0>,
+ <&pcieb_lpcg 1>,
+ <&pcieb_lpcg 2>,
+ <&phyx2_lpcg 1>,
+ <&phyx2_lpcg 0>,
+ <&phyx2_crr0_lpcg 0>,
+ <&pcieb_crr3_lpcg 0>,
+ <&pciea_crr2_lpcg 0>,
+ <&misc_crr5_lpcg 0>,
+ <&pcie_wifi_refclk_gate>;
+ clock-names = "pcie", "pcie_bus", "pcie_inbound_axi",
+ "pcie_phy", "pcie_phy_pclk", "phy_per",
+ "pcie_per", "pciex2_per", "misc_per",
+ "pcie_ext";
+ epdev_on-supply = <&reg_module_wifi>;
+ ext_osc = <1>;
+ fsl,max-link-speed = <1>;
+ reset-gpio = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pwm_lvds1 {
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_bkl>;
+};
+
+/* Apalis PWM3, MXM3 pin 6 */
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0>;
+ #pwm-cells = <3>;
+};
+
+/* Apalis PWM4, MXM3 pin 8 */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ #pwm-cells = <3>;
+};
+
+/* Apalis PWM1, MXM3 pin 2 */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ #pwm-cells = <3>;
+};
+
+/* Apalis PWM2, MXM3 pin 4 */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ #pwm-cells = <3>;
+};
+
+&rpmsg0{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90000000 0x0 0x20000>;
+ memory-region = <&vdevbuffer>;
+};
+
+&rpmsg1{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90100000 0x0 0x20000>;
+ memory-region = <&vdevbuffer>;
+};
+
+&sai1 {
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai1_lpcg 0>; /* FIXME: should be sai1, original code is 0 */
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+};
+
+/* Apalis SATA1 */
+&sata {
+ clocks = <&sata_lpcg 0>,
+ <&phyx1_lpcg 0>,
+ <&phyx1_lpcg 1>,
+ <&phyx1_lpcg 2>,
+ <&phyx2_crr0_lpcg 0>,
+ <&phyx1_crr1_lpcg 0>,
+ <&pciea_crr2_lpcg 0>,
+ <&pcieb_crr3_lpcg 0>,
+ <&sata_crr4_lpcg 0>,
+ <&misc_crr5_lpcg 0>,
+ <&phyx2_lpcg 0>,
+ <&phyx2_lpcg 1>,
+ <&phyx1_lpcg 3>,
+ <&pcie_sata_refclk_gate>;
+ clock-names = "sata", "sata_ref", "epcs_tx", "epcs_rx",
+ "per_clk0", "per_clk1", "per_clk2",
+ "per_clk3", "per_clk4", "per_clk5",
+ "phy_pclk0", "phy_pclk1", "phy_apbclk",
+ "sata_ext";
+ ext_osc = <1>;
+};
+
+/* Apalis SPDIF1 */
+&spdif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>;
+ assigned-clock-rates = <786432000>, <49152000>, <24576000>;
+ status = "okay";
+};
+
+&thermal_zones {
+ pmic-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens IMX_SC_R_PMIC_0>;
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ cooling_maps_map0: map0 {
+ trip = <&pmic_alert0>;
+ };
+ };
+ };
+};
+
+&usb3phynop1 {
+ status = "okay";
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+ pinctrl-names = "idle", "active";
+ pinctrl-0 = <&pinctrl_usb_hsic_idle>;
+ pinctrl-1 = <&pinctrl_usb_hsic_active>;
+ adp-disable;
+ disable-over-current;
+ hnp-disable;
+ srp-disable;
+};
+
+&usbphynop2 {
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
+
+/* Apalis USBO1 */
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ adp-disable;
+ ci-disable-lpm;
+ hnp-disable;
+ over-current-active-low;
+ power-active-high;
+ srp-disable;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_mmc1_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_mmc1_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_mmc1_cd>;
+ bus-width = <8>;
+ cd-gpios = <&lsio_gpio2 9 GPIO_ACTIVE_LOW>; /* Apalis MMC1_CD# */
+ no-1-8-v;
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_sd1_cd>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_sd1_cd>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_sd1_cd>;
+ bus-width = <4>;
+ cd-gpios = <&lsio_gpio4 12 GPIO_ACTIVE_LOW>; /* Apalis SD1_CD# */
+ no-1-8-v;
+};
+
+&vpu_decoder {
+ compatible = "nxp,imx8qm-b0-vpudec";
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg-csr = <0x2d080000>;
+ core_type = <2>;
+ status = "okay";
+};
+
+&vpu_ts {
+ compatible = "nxp,imx8qm-b0-vpu-ts";
+ boot-region = <&ts_boot>;
+ reg-csr = <0x2d0b0000>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ compatible = "nxp,imx8qm-b0-vpuenc";
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg-rpc-system = <0x40000000>;
+ resolution-max = <1920 1920>;
+ power-domains = <&pd IMX_SC_R_VPU_ENC_0>, <&pd IMX_SC_R_VPU_ENC_1>,
+ <&pd IMX_SC_R_VPU>;
+ power-domain-names = "vpuenc1", "vpuenc2", "vpu";
+ mbox-names = "enc1_tx0", "enc1_tx1", "enc1_rx",
+ "enc2_tx0", "enc2_tx1", "enc2_rx";
+ mboxes = <&mu1_m0 0 0
+ &mu1_m0 0 1
+ &mu1_m0 1 0
+ &mu2_m0 0 0
+ &mu2_m0 0 1
+ &mu2_m0 1 0>;
+ status = "okay";
+
+ vpu_enc_core0: core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1090000 0x10000>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+
+ vpu_enc_core1: core1@1040000 {
+ compatible = "fsl,imx8-mu2-vpu-m0";
+ reg = <0x1040000 0x20000>;
+ reg-csr = <0x10A0000 0x10000>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <18>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
index fd1faaca1909..6b1e6f299fb1 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -30,7 +30,7 @@ dma_subsys: bus@5a000000 {
<&spi0_lpcg 1>;
clock-names = "per", "ipg";
assigned-clocks = <&clk IMX_SC_R_SPI_0 IMX_SC_PM_CLK_PER>;
- assigned-clock-rates = <20000000>;
+ assigned-clock-rates = <60000000>;
power-domains = <&pd IMX_SC_R_SPI_0>;
dma-names = "tx","rx";
dmas = <&edma2 1 0 0>, <&edma2 0 0 1>;
@@ -329,6 +329,7 @@ dma_subsys: bus@5a000000 {
adc0: adc@5a880000 {
compatible = "fsl,imx8qxp-adc";
+ #io-channel-cells = <1>;
reg = <0x5a880000 0x10000>;
interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
@@ -343,6 +344,7 @@ dma_subsys: bus@5a000000 {
adc1: adc@5a890000 {
compatible = "fsl,imx8qxp-adc";
+ #io-channel-cells = <1>;
reg = <0x5a890000 0x10000>;
interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
index ff196f39949c..237f741dc541 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -27,6 +27,54 @@ lsio_subsys: bus@5d000000 {
clock-output-names = "lsio_bus_clk";
};
+ pwm0: pwm@5d000000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x5d000000 0x10000>;
+ clock-names = "ipg", "per";
+ clocks = <&pwm0_lpcg 4>,
+ <&pwm0_lpcg 1>;
+ assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@5d010000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x5d010000 0x10000>;
+ clock-names = "ipg", "per";
+ clocks = <&pwm1_lpcg 4>,
+ <&pwm1_lpcg 1>;
+ assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@5d020000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x5d020000 0x10000>;
+ clock-names = "ipg", "per";
+ clocks = <&pwm2_lpcg 4>,
+ <&pwm2_lpcg 1>;
+ assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@5d030000 {
+ compatible = "fsl,imx8qm-pwm", "fsl,imx27-pwm";
+ reg = <0x5d030000 0x10000>;
+ clock-names = "ipg", "per";
+ clocks = <&pwm3_lpcg 4>,
+ <&pwm3_lpcg 1>;
+ assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
lsio_gpio0: gpio@5d080000 {
reg = <0x5d080000 0x10000>;
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts
new file mode 100644
index 000000000000..db428d945ab6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Aster Board";
+ compatible = "toradex,colibri-imx8x-aster",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp",
+ "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts
new file mode 100644
index 000000000000..e3d9f450286c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri-imx8x-eval-v3",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp", "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts
new file mode 100644
index 000000000000..f864ab3cdb52
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx8x-iris-v2",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp", "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts
new file mode 100644
index 000000000000..a89ec2efbc8a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX on Colibri Iris Board";
+ compatible = "toradex,colibri-imx8x-iris",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp", "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi
new file mode 100644
index 000000000000..dae37a4281aa
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8dx.dtsi"
+#include "imx8x-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8DX Module";
+ compatible = "toradex,colibri-imx8x", "fsl,imx8dx";
+};
+
+&imx8_gpu_ss {
+ reg = <0x80000000 0x40000000>, <0x0 0x08000000>;
+ reg-names = "phys_baseaddr", "contiguous_mem";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index 93b44efdbc52..df873eb12021 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -430,18 +430,26 @@
#define MX8MM_IOMUXC_SAI1_MCLK_SIM_M_HRESP 0x1AC 0x414 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0x1B0 0x418 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXFS_UART1_TX 0x1B0 0x418 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI2_RXFS_UART1_RX 0x1B0 0x418 0x4F4 0x4 0x2
#define MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x1B0 0x418 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0 0x1B0 0x418 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0x1B4 0x41C 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXC_UART1_RX 0x1B4 0x41C 0x4F4 0x4 0x3
+#define MX8MM_IOMUXC_SAI2_RXC_UART1_TX 0x1B4 0x41C 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x1B4 0x41C 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI2_RXC_SIM_M_HSIZE1 0x1B4 0x41C 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0x1B8 0x420 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0 0x1B8 0x420 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_UART1_RTS_B 0x1B8 0x420 0x4F0 0x4 0x2
+#define MX8MM_IOMUXC_SAI2_RXD0_UART1_CTS_B 0x1B8 0x420 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI2_RXD0_GPIO4_IO23 0x1B8 0x420 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2 0x1B8 0x420 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0x1BC 0x424 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1 0x1BC 0x424 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_UART1_CTS_B 0x1BC 0x424 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_UART1_RTS_B 0x1BC 0x424 0x4F0 0x4 0x3
#define MX8MM_IOMUXC_SAI2_TXFS_GPIO4_IO24 0x1BC 0x424 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI2_TXFS_SIM_M_HWRITE 0x1BC 0x424 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0x1C0 0x428 0x000 0x0 0x0
@@ -464,21 +472,37 @@
#define MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0x1D0 0x438 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI3_RXC_GPT1_CLK 0x1D0 0x438 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_RXC_SAI5_RX_BCLK 0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x1D0 0x438 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_RTS_B 0x1D0 0x438 0x4F8 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DTE_CTS_B 0x1D0 0x438 0x4F8 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DTE_RTS_B 0x1D0 0x438 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x1D0 0x438 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_RXC_TPSMP_HTRANS1 0x1D0 0x438 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0x1D4 0x43C 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI3_RXD_GPT1_COMPARE1 0x1D4 0x43C 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_RXD_SAI5_RX_DATA0 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x1D4 0x43C 0x4F8 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_CTS_B 0x1D4 0x43C 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DTE_RTS_B 0x1D4 0x43C 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DTE_CTS_B 0x1D4 0x43C 0x4F8 0x4 0x3
#define MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30 0x1D4 0x43C 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_RXD_TPSMP_HDATA0 0x1D4 0x43C 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0x1D8 0x440 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2 0x1D8 0x440 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1 0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x1D8 0x440 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_TX 0x1D8 0x440 0x4FC 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_RX 0x1D8 0x440 0x4FC 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX 0x1D8 0x440 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x1D8 0x440 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1 0x1D8 0x440 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0x1DC 0x444 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2 0x1DC 0x444 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_RX 0x1DC 0x444 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x1DC 0x444 0x4FC 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX 0x1DC 0x444 0x4FC 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_TX 0x1DC 0x444 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0 0x1DC 0x444 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2 0x1DC 0x444 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0x1E0 0x448 0x000 0x0 0x0
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
new file mode 100755
index 000000000000..86604820999e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/ {
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mm-wm8904";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Headphone Jack", "MICBIAS",
+ "IN1L", "Headphone Jack";
+ simple-audio-card,widgets =
+ "Microphone", "Headphone Jack",
+ "Headphone", "Headphone Jack",
+ "Line", "Line In Jack";
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&wm8904_1a>;
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ };
+ };
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+ status = "okay";
+
+ spidev20: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+ };
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+ status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+ status = "okay";
+};
+
+&hwmon_temp {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ status = "okay";
+
+ /* Audio Codec */
+ wm8904_1a: codec@1a {
+ compatible = "wlf,wm8904";
+ #sound-dai-cells = <0>;
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ clock-names = "mclk";
+ reg = <0x1a>;
+ DCVDD-supply = <&reg_3p3v>;
+ DBVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ CPVDD-supply = <&reg_3p3v>;
+ MICVDD-supply = <&reg_3p3v>;
+ };
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+ status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+ status = "okay";
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+ status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+ status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart2 {
+ status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+ status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
new file mode 100755
index 000000000000..4ffb60848db8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mm-nau8822";
+ simple-audio-card,routing =
+ "Headphones", "LHP",
+ "Headphones", "RHP",
+ "Speaker", "LSPK",
+ "Speaker", "RSPK",
+ "Line Out", "AUXOUT1",
+ "Line Out", "AUXOUT2",
+ "LAUX", "Line In",
+ "RAUX", "Line In",
+ "LMICP", "Mic In",
+ "RMICP", "Mic In";
+ simple-audio-card,widgets =
+ "Headphones", "Headphones",
+ "Line Out", "Line Out",
+ "Speaker", "Speaker",
+ "Microphone", "Mic In",
+ "Line", "Line In";
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&nau8822_1a>;
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ };
+ };
+};
+
+&gpio_expander_21 {
+ status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ /* Audio Codec */
+ nau8822_1a: codec-nau@1a {
+ compatible = "nuvoton,nau8822";
+ #sound-dai-cells = <0>;
+ reg = <0x1a>;
+ };
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+ max-frequency = <100000000>;
+};
+
+&wm8904_1a {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
new file mode 100755
index 000000000000..d7cacf6ee42a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini on Dahlia Board";
+ compatible = "toradex,verdin-imx8mm-nonwifi-dahlia",
+ "toradex,verdin-imx8mm-nonwifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
new file mode 100755
index 000000000000..8a85b31e8b65
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2019-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mm-nonwifi-dev",
+ "toradex,verdin-imx8mm-nonwifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
new file mode 100755
index 000000000000..c488a4111cdb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+&gpio3 {
+ gpio-line-names = "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_64",
+ "SODIMM_21",
+ "SODIMM_206",
+ "SODIMM_76",
+ "SODIMM_56",
+ "SODIMM_58",
+ "SODIMM_60",
+ "SODIMM_62",
+ "SODIMM_162",
+ "SODIMM_164",
+ "SODIMM_166",
+ "SODIMM_168",
+ "SODIMM_66",
+ "SODIMM_17",
+ "",
+ "SODIMM_156",
+ "SODIMM_160",
+ "SODIMM_244",
+ "SODIMM_250",
+ "SODIMM_48",
+ "SODIMM_44",
+ "SODIMM_42",
+ "SODIMM_46";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_102",
+ "SODIMM_90",
+ "SODIMM_92",
+ "SODIMM_94",
+ "SODIMM_96",
+ "SODIMM_100",
+ "SODIMM_148",
+ "SODIMM_152",
+ "SODIMM_154",
+ "SODIMM_174",
+ "SODIMM_120",
+ "SODIMM_104",
+ "SODIMM_106",
+ "SODIMM_108",
+ "SODIMM_112",
+ "SODIMM_114",
+ "SODIMM_116",
+ "SODIMM_150",
+ "SODIMM_118",
+ "",
+ "SODIMM_88",
+ "SODIMM_149",
+ "SODIMM_147",
+ "SODIMM_36",
+ "SODIMM_32",
+ "SODIMM_30",
+ "SODIMM_34",
+ "SODIMM_38",
+ "SODIMM_252",
+ "SODIMM_133",
+ "SODIMM_135",
+ "SODIMM_129";
+};
+
+&usdhc3 {
+ bus-width = <4>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
new file mode 100755
index 000000000000..8fe257aa9ef9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini WB on Dahlia Board";
+ compatible = "toradex,verdin-imx8mm-wifi-dahlia",
+ "toradex,verdin-imx8mm-wifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
new file mode 100755
index 000000000000..ae71a5d3b169
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2019-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mm-wifi-dev",
+ "toradex,verdin-imx8mm-wifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
new file mode 100755
index 000000000000..842c1760d632
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/ {
+ reg_wifi_en: regulator-wifi-en {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+ regulator-name = "PDn_AW-CM276NF";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <2000>;
+ };
+};
+
+/* On-module Wi-Fi */
+&usdhc3 {
+ bus-width = <4>;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_wifi_ctrl>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_wifi_ctrl>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_wifi_ctrl>;
+ vmmc-supply = <&reg_wifi_en>;
+ wifi-host;
+ status = "okay";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_64",
+ "SODIMM_21",
+ "SODIMM_206",
+ "SODIMM_76",
+ "SODIMM_56",
+ "SODIMM_58",
+ "SODIMM_60",
+ "SODIMM_62",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_66",
+ "SODIMM_17",
+ "",
+ "",
+ "",
+ "SODIMM_244",
+ "",
+ "SODIMM_48",
+ "SODIMM_44",
+ "SODIMM_42",
+ "SODIMM_46";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_102",
+ "SODIMM_90",
+ "SODIMM_92",
+ "SODIMM_94",
+ "SODIMM_96",
+ "SODIMM_100",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_120",
+ "SODIMM_104",
+ "SODIMM_106",
+ "SODIMM_108",
+ "SODIMM_112",
+ "SODIMM_114",
+ "SODIMM_116",
+ "",
+ "SODIMM_118",
+ "",
+ "SODIMM_88",
+ "SODIMM_149",
+ "SODIMM_147",
+ "SODIMM_36",
+ "SODIMM_32",
+ "SODIMM_30",
+ "SODIMM_34",
+ "SODIMM_38",
+ "SODIMM_252",
+ "SODIMM_133",
+ "SODIMM_135",
+ "SODIMM_129";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
new file mode 100755
index 000000000000..d03e33a4142f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -0,0 +1,1394 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2019-2021 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mm.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc0,115200 earlycon";
+ stdout-path = &uart1;
+ };
+
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ /* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+ enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+ power-supply = <&reg_3p3v>;
+ /* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+ pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ /* fixed clock dedicated to SPI CAN controller */
+ clk40m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <40000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ debounce-interval = <10>;
+ /* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+ gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ label = "Wake-Up";
+ linux,code = <KEY_WAKEUP>;
+ wakeup-source;
+ };
+ };
+
+ /* Carrier Board Supply */
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "REG_3P3V";
+ };
+
+ reg_aux_usb: regulator-aux-usb {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "REG_AUX_USB";
+ };
+
+ reg_mipi_phy: regulator-mipi-phy {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <1000000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-name = "REG_MIPI_PHY";
+ };
+
+ reg_ethphy: regulator-ethphy {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+ off-on-delay = <500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_eth>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "V3.3_ETH";
+ startup-delay-us = <200000>;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin USB1_EN */
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb1_en>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "usb_otg1_vbus";
+ };
+
+ reg_usb_otg2_vbus: regulator-usb-otg2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin USB_2_EN (SODIMM 185) */
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb2_en>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "usb_otg2_vbus";
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin SD_1_PWR_EN (SODIMM 76) */
+ gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "V3.3_SD";
+ startup-delay-us = <2000>;
+ off-on-delay = <100000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* use the kernel configuration settings instead */
+ /delete-node/ linux,cma;
+
+ rpmsg_reserved: rpmsg@b8000000 {
+ no-map;
+ reg = <0 0xb8000000 0 0x400000>;
+ };
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2_reg>;
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+};
+
+/* Verdin CAN_1 and CAN_2 (on-module) */
+&ecspi3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>,
+ <&gpio1 5 GPIO_ACTIVE_LOW>;
+ /* This property is required, even if marked as obsolete in the doku */
+ fsl,spi-num-chipselects = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+
+ can1: can@0 {
+ compatible = "microchip,mcp2517fd";
+ clocks = <&clk40m>;
+ gpio-controller;
+ interrupt-parent = <&gpio1>;
+ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+ microchip,clock-allways-on;
+ microchip,clock-out-div = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_int>;
+ reg = <0>;
+ spi-max-frequency = <8500000>;
+ };
+
+ can2: can@1 {
+ compatible = "microchip,mcp2517fd";
+ clocks = <&clk40m>;
+ gpio-controller;
+ interrupt-parent = <&gpio1>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can2_int>;
+ reg = <1>;
+ spi-max-frequency = <2000000>;
+ /* not assembled */
+ status = "disabled";
+ };
+};
+
+/* Verdin ETH_1 (on-module PHY) */
+&fec1 {
+ fsl,magic-packet;
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&reg_ethphy>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec1>;
+ pinctrl-1 = <&pinctrl_fec1_sleep>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ interrupt-parent = <&gpio1>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+#if 0
+ flash0: mt25qu256aba@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt25qu256aba";
+ reg = <0>;
+ spi-max-frequency = <80000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ };
+#endif
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_216",
+ "SODIMM_19",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_220",
+ "SODIMM_222",
+ "",
+ "SODIMM_218",
+ "SODIMM_155",
+ "SODIMM_157",
+ "SODIMM_185",
+ "SODIMM_187";
+};
+
+&gpio2 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_84",
+ "SODIMM_78",
+ "SODIMM_74",
+ "SODIMM_80",
+ "SODIMM_82",
+ "SODIMM_70",
+ "SODIMM_72";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_131",
+ "",
+ "SODIMM_91",
+ "SODIMM_16",
+ "SODIMM_15",
+ "SODIMM_208",
+ "SODIMM_137",
+ "SODIMM_139",
+ "SODIMM_141",
+ "SODIMM_143",
+ "SODIMM_196",
+ "SODIMM_200",
+ "SODIMM_198",
+ "SODIMM_202",
+ "",
+ "",
+ "SODIMM_55",
+ "SODIMM_53",
+ "SODIMM_95",
+ "SODIMM_93",
+ "SODIMM_14",
+ "SODIMM_12",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_210",
+ "SODIMM_212",
+ "SODIMM_151",
+ "SODIMM_153";
+
+ ctrl_sleep_moci {
+ gpio-hog;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ line-name = "CTRL_SLEEP_MOCI#";
+ output-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+ };
+};
+
+/* On-module I2C */
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ pmic: pca9450@25 {
+ compatible = "nxp,pca9450";
+ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ i2c-lt-en = <0x101>;
+ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0x25>;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pca9450,pmic-buck2-uses-i2c-dvs;
+ /* Run/Standby voltage */
+ pca9450,pmic-buck2-dvs-voltage = <950000>, <850000>;
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "buck3";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck4_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "buck4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ rtc_i2c: rtc@32 {
+ compatible = "epson,rx8130";
+ reg = <0x32>;
+ };
+
+ adc@49 {
+ compatible = "ti,ads1015";
+ reg = <0x49>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Verdin I2C_1 (ADC_4 - ADC_3) */
+ channel@0 {
+ reg = <0>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_4 - ADC_1) */
+ channel@1 {
+ reg = <1>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_3 - ADC_1) */
+ channel@2 {
+ reg = <2>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_2 - ADC_1) */
+ channel@3 {
+ reg = <3>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_4 */
+ channel@4 {
+ reg = <4>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_3 */
+ channel@5 {
+ reg = <5>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_2 */
+ channel@6 {
+ reg = <6>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_1 */
+ channel@7 {
+ reg = <7>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+ };
+
+ eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ clock-frequency = <10000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+};
+
+/* Verdin I2C_3_HDMI N/A */
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+ gpio_expander_21: gpio-expander@21 {
+ compatible = "nxp,pcal6416";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x21>;
+ status = "disabled";
+ vcc-supply = <&reg_3p3v>;
+ };
+
+ lvds_ti_sn65dsi83: bridge@2c {
+ compatible = "ti,sn65dsi83";
+ /* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ enable-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+ reg = <0x2c>;
+ status = "disabled";
+ };
+
+ /* Current measurement into module VCC */
+ hwmon: hwmon@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ status = "disabled";
+ };
+
+ hdmi_lontium_lt8912: hdmi@48 {
+ compatible = "lontium,lt8912";
+ ddc-i2c-bus = <&i2c2>;
+ /* Verdin PWM_3_DSI (SODIMM 19) */
+ hpd-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+ reg = <0x48>;
+ /* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+ };
+
+ atmel_mxt_ts: touch@4a {
+ compatible = "atmel,maxtouch";
+ /* Verdin GPIO_9_DSI (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused */
+ interrupt-parent = <&gpio3>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+ reg = <0x4a>;
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+ reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ /* temperature sensor on carrier board */
+ hwmon_temp: hwmontemp@4f {
+ compatible = "ti,tmp75c";
+ reg = <0x4f>;
+ status = "disabled";
+ };
+
+ /* EEPROM on display adapter (MIPI DSI Display Adapter) */
+ eeprom_display_adapter: eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ status = "disabled";
+ };
+
+ /* EEPROM on carrier board */
+ eeprom_carrier_board: eeprom@57 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x57>;
+ status = "disabled";
+ };
+};
+
+&mu {
+ status = "okay";
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_100M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ assigned-clock-rates = <10000000>, <100000000>, <250000000>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>,
+ <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ epdev_on-supply = <&reg_3p3v>;
+ ext_osc = <0>;
+ l1ss-disabled;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reserved-region = <&rpmsg_reserved>;
+ /* PCIE_1_RESET# (SODIMM 244) */
+ reset-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_1>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_2>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_3>;
+ #pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+ #sound-dai-cells = <0>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux console */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+};
+
+/* Verdin UART_1 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+};
+
+/* Verdin UART_4 */
+/*
+ * resource allocated to M4 by default, must not be accessed from A-35 or you
+ * get an OOPS
+ */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&usbmisc1 {
+ vbus-wakeup-supply = <&reg_aux_usb>;
+};
+
+&usbmisc2 {
+ vbus-wakeup-supply = <&reg_aux_usb>;
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ over-current-active-low;
+ picophy,dc-vol-level-adjust = <7>;
+ picophy,pre-emp-curr-control = <3>;
+ vbus-supply = <&reg_usb_otg1_vbus>;
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+ dr_mode = "host";
+ over-current-active-low;
+ picophy,dc-vol-level-adjust = <7>;
+ picophy,pre-emp-curr-control = <3>;
+ vbus-supply = <&reg_usb_otg2_vbus>;
+};
+
+&usbphynop1 {
+ vcc-supply = <&reg_aux_usb>;
+};
+
+&usbphynop2 {
+ vcc-supply = <&reg_aux_usb>;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+ bus-width = <8>;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ pm-ignore-notify;
+ status = "okay";
+ /* TODO Strobe */
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_h1 {
+ status = "okay";
+};
+
+&wdog1 {
+ fsl,ext-reset-output;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+ <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+ <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+ <&pinctrl_pmic_tpm_ena>;
+
+ pinctrl_can1_int: can1intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x146 /* CAN_1_SPI_INT#_1.8V */
+ >;
+ };
+
+ pinctrl_can2_int: can2intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x106 /* CAN_2_SPI_INT#_1.8V */
+ >;
+ };
+
+ pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x106 /* SODIMM 256 */
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x6 /* SODIMM 196 */
+ MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x6 /* SODIMM 200 */
+ MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x6 /* SODIMM 198 */
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x6 /* SODIMM 202 */
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x6 /* CAN_SPI_SCK_1.8V */
+ MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x6 /* CAN_SPI_MOSI_1.8V */
+ MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x6 /* CAN_SPI_MISO_1.8V */
+ MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x6 /* CAN_1_SPI_CS_1.8V# */
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x146 /* CAN_2_SPI_CS#_1.8V */
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x146
+ >;
+ };
+
+ pinctrl_fec1_sleep: fec1-sleepgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18 0x1f
+ MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19 0x1f
+ MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20 0x1f
+ MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_GPIO1_IO23 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x1f
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x106
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x106 /* SODIMM 52 */
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x106 /* SODIMM 54 */
+ MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B 0x106 /* SODIMM 64 */
+ MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x106 /* SODIMM 66 */
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x106 /* SODIMM 56 */
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x106 /* SODIMM 58 */
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x106 /* SODIMM 60 */
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x106 /* SODIMM 62 */
+ >;
+ };
+
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x106 /* SODIMM 206 */
+ >;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x106 /* SODIMM 208 */
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x106 /* SODIMM 210 */
+ >;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27 0x106 /* SODIMM 212 */
+ >;
+ };
+
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x106 /* SODIMM 216 */
+ >;
+ };
+
+ pinctrl_gpio6: gpio6grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x106 /* SODIMM 218 */
+ >;
+ };
+
+ pinctrl_gpio7: gpio7grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x106 /* SODIMM 220 */
+ >;
+ };
+
+ pinctrl_gpio8: gpio8grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x106 /* SODIMM 222 */
+ >;
+ };
+
+ /* Verdin GPIO_9_DSI (pulled-up as active-low) */
+ pinctrl_gpio_9_dsi: gpio9dsigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x146 /* SODIMM 17 */
+ >;
+ };
+
+ /* Verdin GPIO_10_DSI (pulled-up as active-low) */
+ pinctrl_gpio_10_dsi: gpio10dsigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x146 /* SODIMM 21 */
+ >;
+ };
+
+ pinctrl_gpio_hog1: gpiohog1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20 0x106 /* SODIMM 88 */
+ MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1 0x106 /* SODIMM 90 */
+ MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2 0x106 /* SODIMM 92 */
+ MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3 0x106 /* SODIMM 94 */
+ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x106 /* SODIMM 96 */
+ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x106 /* SODIMM 100 */
+ MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x106 /* SODIMM 102 */
+ MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x106 /* SODIMM 104 */
+ MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x106 /* SODIMM 106 */
+ MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x106 /* SODIMM 108 */
+ MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x106 /* SODIMM 112 */
+ MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x106 /* SODIMM 114 */
+ MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x106 /* SODIMM 116 */
+ MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x106 /* SODIMM 118 */
+ MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10 0x106 /* SODIMM 120 */
+ >;
+ };
+
+ pinctrl_gpio_hog2: gpiohog2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x106 /* SODIMM 91 */
+ >;
+ };
+
+ pinctrl_gpio_hog3: gpiohog3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x146 /* SODIMM 157 */
+ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x146 /* SODIMM 187 */
+ >;
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x146 /* SODIMM 252 */
+ >;
+ };
+
+ /* On-module I2C */
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000146 /* PMIC_I2C_SCL */
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000146 /* PMIC_I2C_SDA */
+ >;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14 0x146 /* PMIC_I2C_SCL */
+ MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15 0x146 /* PMIC_I2C_SDA */
+ >;
+ };
+
+ /* Verdin I2C_4_CSI */
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000146 /* SODIMM 55 */
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000146 /* SODIMM 53 */
+ >;
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x146 /* SODIMM 55 */
+ MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17 0x146 /* SODIMM 53 */
+ >;
+ };
+
+ /* Verdin I2C_2_DSI */
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000146 /* SODIMM 95 */
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000146 /* SODIMM 93 */
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x146 /* SODIMM 95 */
+ MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x146 /* SODIMM 93 */
+ >;
+ };
+
+ /* Verdin I2C_1 */
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000146 /* SODIMM 14 */
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000146 /* SODIMM 12 */
+ >;
+ };
+
+ pinctrl_i2c4_gpio: i2c4gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20 0x146 /* SODIMM 14 */
+ MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0x146 /* SODIMM 12 */
+ >;
+ };
+
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+ pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x6 /* SODIMM 42 */
+ >;
+ };
+
+ /* Verdin I2S_2_D_OUT shared with SAI5 */
+ pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x6 /* SODIMM 46 */
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x6 /* SODIMM 244 */
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x6 /* PMIC_EN_PCIe_CLK, unused */
+ >;
+ };
+
+ pinctrl_pmic: pmicirqgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141 /* PMIC_INT# */
+ >;
+ };
+
+ /* Verdin PWM_3_DSI shared with GPIO1_IO1 */
+ pinctrl_pwm_1: pwm1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT 0x6 /* SODIMM 19 */
+ >;
+ };
+
+ pinctrl_pwm_2: pwm2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x6 /* SODIMM 15 */
+ >;
+ };
+
+ pinctrl_pwm_3: pwm3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x6 /* SODIMM 16 */
+ >;
+ };
+
+ /* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM1_OUT */
+ pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsihpdgpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x106 /* SODIMM 19 */
+ >;
+ };
+
+ pinctrl_reg_eth: regethgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x146 /* PMIC_EN_ETH */
+ >;
+ };
+
+ pinctrl_reg_usb1_en: regusb1engrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x106 /* SODIMM 155 */
+ >;
+ };
+
+ pinctrl_reg_usb2_en: regusb2engrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x106 /* SODIMM 185 */
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0x6 /* SODIMM 32 */
+ MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0x6 /* SODIMM 30 */
+ MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0x6 /* SODIMM 38 */
+ MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0x6 /* SODIMM 36 */
+ MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0x6 /* SODIMM 34 */
+ >;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0x6 /* SODIMM 48 */
+ MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0x6 /* SODIMM 44 */
+ MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0x6 /* SODIMM 42 */
+ MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0x6 /* SODIMM 46 */
+ >;
+ };
+
+ /* control signal for optional ATTPM20P or SE050 */
+ pinctrl_pmic_tpm_ena: pmictpmenagrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x106 /* PMIC_TPM_ENA */
+ >;
+ };
+
+ pinctrl_tsp: tspgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x6 /* SODIMM 148 */
+ MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x6 /* SODIMM 152 */
+ MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x6 /* SODIMM 154 */
+ MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x146 /* SODIMM 174 */
+ MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x6 /* SODIMM 150 */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_RXFS_UART1_TX 0x146 /* SODIMM 149 */
+ MX8MM_IOMUXC_SAI2_RXC_UART1_RX 0x146 /* SODIMM 147 */
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_TX 0x146 /* SODIMM 129 */
+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_RX 0x146 /* SODIMM 131 */
+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x146 /* SODIMM 133 */
+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x146 /* SODIMM 135 */
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x146 /* SODIMM 137 */
+ MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x146 /* SODIMM 139 */
+ MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x146 /* SODIMM 141 */
+ MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x146 /* SODIMM 143 */
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x146 /* SODIMM 151 */
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x146 /* SODIMM 153 */
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d0
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d0
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d0
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d0
+ MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d4
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d4
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d4
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d4
+ MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d6
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d6
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d6
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d6
+ MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x196
+ >;
+ };
+
+ pinctrl_usdhc2_cd: usdhc2cdgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x6 /* SODIMM 84 */
+ >;
+ };
+
+ pinctrl_usdhc2_cd_sleep: usdhc2cdslpgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x0 /* SODIMM 84 */
+ >;
+ };
+
+ pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6 /* SODIMM 76 */
+ >;
+ };
+
+ /*
+ * Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the
+ * on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here.
+ */
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 /* SODIMM 78 */
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90 /* SODIMM 74 */
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90 /* SODIMM 80 */
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x90 /* SODIMM 82 */
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x90 /* SODIMM 70 */
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x90 /* SODIMM 72 */
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x94
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x94
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x94
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x96
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x96
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x96
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10
+ >;
+ };
+
+ /* Avoid backfeeding with removed card power */
+ pinctrl_usdhc2_sleep: usdhc2slpgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x0
+ >;
+ };
+
+ /* On-module Wi-Fi/BT or type specific SDHC interface (e.g. on X52 extension slot of Verdin Development Board */
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x150
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x150
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x150
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x150
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x150
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x150
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x154
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x154
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x154
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x154
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x154
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x154
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x156
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x156
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x156
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x156
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x156
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x156
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 /* PMIC_WDI */
+ >;
+ };
+
+ pinctrl_wifi_ctrl: wifictrlgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x46 /* WIFI_WKUP_BT */
+ MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x146 /* WIFI_W_WKUP_HOST */
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x46 /* WIFI_WKUP_WLAN */
+ >;
+ };
+
+ pinctrl_wifi_i2s: bti2sgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK 0x6 /* WIFI_TX_BCLK */
+ MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0 0x6 /* WIFI_TX_DATA0 */
+ MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC 0x6 /* WIFI_TX_SYNC */
+ MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0 0x6 /* WIFI_RX_DATA0 */
+ >;
+ };
+
+ pinctrl_wifi_pwr_en: wifipwrengrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x6 /* PMIC_EN_WIFI */
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
new file mode 100755
index 000000000000..e44bfb5efe9d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/ {
+ /* Carrier Board Supply +V1.8 */
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "+V1.8_SW";
+ };
+
+ /* Carrier Board Supply +V3.3 */
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SW";
+ };
+
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mp-wm8904";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Headphone Jack", "MICBIAS",
+ "IN1L", "Headphone Jack";
+ simple-audio-card,widgets =
+ "Microphone", "Headphone Jack",
+ "Headphone", "Headphone Jack",
+ "Line", "Line In Jack";
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&wm8904_1a>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ };
+ };
+
+ sound_hdmi: sound-hdmi {
+ compatible = "fsl,imx-audio-cdnhdmi";
+ model = "audio-hdmi";
+ audio-cpu = <&aud2htx>;
+ hdmi-out;
+ constraint-rate = <44100>,
+ <88200>,
+ <176400>,
+ <32000>,
+ <48000>,
+ <96000>,
+ <192000>;
+ status = "disabled";
+ };
+};
+
+&backlight {
+ power-supply = <&reg_3p3v>;
+};
+
+/* Verdin SPI_1 */
+&ecspi1 {
+ status = "okay";
+
+ spidev10: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+ };
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+ status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+ status = "okay";
+};
+
+&eqos {
+ status = "okay";
+};
+
+&flexcan1 {
+ status = "okay";
+};
+
+&flexcan2 {
+ status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+ status = "okay";
+};
+
+&hwmon_temp {
+ status = "okay";
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* Audio Codec */
+ wm8904_1a: codec@1a {
+ compatible = "wlf,wm8904";
+ #sound-dai-cells = <0>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1>;
+ clock-names = "mclk";
+ reg = <0x1a>;
+ DCVDD-supply = <&reg_1p8v>;
+ DBVDD-supply = <&reg_1p8v>;
+ AVDD-supply = <&reg_1p8v>;
+ CPVDD-supply = <&reg_1p8v>;
+ MICVDD-supply = <&reg_1p8v>;
+ };
+};
+
+/* Verdin PCIE_1 */
+&pcie {
+ epdev_on-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&pcie_phy{
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm3 {
+ status = "okay";
+};
+
+&reg_usdhc2_vmmc {
+ vin-supply = <&reg_3p3v>;
+};
+
+/* VERDIN I2S_1 */
+&sai1 {
+ status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart1 {
+ status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart2 {
+ status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux Console */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usb3_phy0 {
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usb3_phy1 {
+ status = "okay";
+};
+
+&usb3_1 {
+ status = "okay";
+};
+
+&usb_dwc3_1 {
+ disable-over-current;
+ status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
new file mode 100755
index 000000000000..dfe66386261e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+#include "imx8mp-verdin-dahlia.dtsi"
+
+/ {
+ reg_eth2phy: regulator-eth2phy {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio_expander_21 4 GPIO_ACTIVE_HIGH>; /* ETH_PWR_EN */
+ off-on-delay = <500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_ETH";
+ startup-delay-us = <200000>;
+ vin-supply = <&reg_3p3v>;
+ };
+
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mp-nau8822";
+ simple-audio-card,routing =
+ "Headphones", "LHP",
+ "Headphones", "RHP",
+ "Speaker", "LSPK",
+ "Speaker", "RSPK",
+ "Line Out", "AUXOUT1",
+ "Line Out", "AUXOUT2",
+ "LAUX", "Line In",
+ "RAUX", "Line In",
+ "LMICP", "Mic In",
+ "RMICP", "Mic In";
+ simple-audio-card,widgets =
+ "Headphones", "Headphones",
+ "Line Out", "Line Out",
+ "Speaker", "Speaker",
+ "Microphone", "Mic In",
+ "Line", "Line In";
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&nau8822_1a>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ };
+ };
+};
+
+&fec {
+ phy-supply = <&reg_eth2phy>;
+ status = "okay";
+};
+
+&gpio_expander_21 {
+ status = "okay";
+ vcc-supply = <&reg_1p8v>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ /* Audio Codec */
+ nau8822_1a: codec-nau@1a {
+ compatible = "nuvoton,nau8822";
+ #sound-dai-cells = <0>;
+ reg = <0x1a>;
+ };
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+ max-frequency = <100000000>;
+};
+
+&wm8904_1a {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dts
new file mode 100755
index 000000000000..72077039bc20
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-nonwifi.dtsi"
+#include "imx8mp-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus on Dahlia Board";
+ compatible = "toradex,verdin-imx8mp-nonwifi-dahlia",
+ "toradex,verdin-imx8mp-nonwifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dts
new file mode 100755
index 000000000000..a3d7034fe247
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-nonwifi.dtsi"
+#include "imx8mp-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mp-nonwifi-dev",
+ "toradex,verdin-imx8mp-nonwifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi
new file mode 100755
index 000000000000..c04c0775a79a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi.dtsi
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+&gpio5 {
+ gpio-line-names = "SODIMM_42",
+ "SODIMM_46",
+ "SODIMM_187",
+ "SODIMM_20",
+ "SODIMM_22",
+ "SODIMM_15",
+ "SODIMM_196",
+ "SODIMM_200",
+ "SODIMM_198",
+ "SODIMM_202",
+ "SODIMM_164",
+ "SODIMM_152",
+ "SODIMM_116",
+ "SODIMM_128",
+ "",
+ "",
+ "SODIMM_55",
+ "SODIMM_53",
+ "SODIMM_95",
+ "SODIMM_93",
+ "SODIMM_14",
+ "SODIMM_12",
+ "SODIMM_129",
+ "SODIMM_131",
+ "SODIMM_137",
+ "SODIMM_139",
+ "SODIMM_147",
+ "SODIMM_149",
+ "SODIMM_151",
+ "SODIMM_153";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+ <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+ <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+ <&pinctrl_hdmi_hog>;
+};
+
+/* Verdin UART_4 */
+/* Often used by the M7 and then should not be enabled here. */
+&uart4 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dts
new file mode 100755
index 000000000000..4dafa67f2d6d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-wifi.dtsi"
+#include "imx8mp-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus WB on Dahlia Board";
+ compatible = "toradex,verdin-imx8mp-wifi-dahlia",
+ "toradex,verdin-imx8mp-wifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dts
new file mode 100755
index 000000000000..94115d613f65
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-wifi.dtsi"
+#include "imx8mp-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus WB on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mp-wifi-dev",
+ "toradex,verdin-imx8mp-wifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi
new file mode 100755
index 000000000000..e7b3fe432de5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi.dtsi
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/ {
+ reg_wifi_en: regulator-wifi-en {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+ regulator-name = "PDn_AW-CM276NF";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <2000>;
+ };
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_42",
+ "SODIMM_46",
+ "SODIMM_187",
+ "SODIMM_20",
+ "SODIMM_22",
+ "SODIMM_15",
+ "SODIMM_196",
+ "SODIMM_200",
+ "SODIMM_198",
+ "SODIMM_202",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_55",
+ "SODIMM_53",
+ "SODIMM_95",
+ "SODIMM_93",
+ "SODIMM_14",
+ "SODIMM_12",
+ "SODIMM_129",
+ "SODIMM_131",
+ "SODIMM_137",
+ "SODIMM_139",
+ "SODIMM_147",
+ "SODIMM_149",
+ "SODIMM_151",
+ "SODIMM_153";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+ <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+ <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>, <&pinctrl_gpio_hog4>,
+ <&pinctrl_hdmi_hog>;
+};
+
+/* On-module Bluetooth */
+&uart4 {
+ fsl,uart-has-rtscts;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bt_uart>;
+ status = "okay";
+};
+
+/* On-module Wi-Fi */
+&usdhc1 {
+ bus-width = <4>;
+ keep-power-in-suspend;
+ max-frequency = <100000000>;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wifi_ctrl>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_wifi_ctrl>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_wifi_ctrl>;
+ vmmc-supply = <&reg_wifi_en>;
+ wifi-host;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
new file mode 100755
index 000000000000..be5b89a89157
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
@@ -0,0 +1,1500 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2020-2021 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mp.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttymxc2,115200 earlycon";
+ stdout-path = &uart3;
+ };
+
+ aliases {
+ /* Ethernet aliases to ensure correct MAC addresses */
+ ethernet0 = &eqos;
+ ethernet1 = &fec;
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ /* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+ enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+ /* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+ pwms = <&pwm3 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ backlight_mezzanine: backlight-mezzanine {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ /* Verdin GPIO 4 (SODIMM 212) */
+ enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ /* Verdin PWM_2 (SODIMM 16) */
+ pwms = <&pwm2 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ /* USB_1 ID */
+ extcon_usb_1_id: usb_1_id {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_1_id>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ debounce-interval = <10>;
+ /* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+ gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
+ label = "Wake-Up";
+ linux,code = <KEY_WAKEUP>;
+ wakeup-source;
+ };
+ };
+
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+ backlight = <&backlight>;
+ data-mapping = "vesa-24";
+ status = "disabled";
+
+ port {
+ panel_lvds_in: endpoint {
+ remote-endpoint = <&lvds_out>;
+ };
+ };
+ };
+
+ reg_aux_usb: regulator-aux-usb {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "AUX_USB";
+ };
+
+ reg_mipi_phy: regulator-mipi-phy {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <1000000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-name = "MIPI_PHY";
+ };
+
+ reg_module_eth1phy: regulator-module-eth1phy {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+ off-on-delay = <500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_eth>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "On-module +V3.3_ETH";
+ startup-delay-us = <200000>;
+ vin-supply = <&buck4_reg>;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin SD_1_PWR_EN (SODIMM 76) */
+ gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SD";
+ startup-delay-us = <2000>;
+ off-on-delay = <100000>;
+ vin-supply = <&buck4_reg>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* use the kernel configuration settings instead */
+ /delete-node/ linux,cma;
+
+ rpmsg_reserved: rpmsg@55800000 {
+ no-map;
+ reg = <0 0x55800000 0 0x800000>;
+ };
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2_reg>;
+};
+
+/* compare with commit d0307f1e31c64 */
+&clk {
+ init-on-array = <IMX8MP_CLK_HSIO_ROOT>;
+};
+
+/* Verdin SPI_1 */
+&ecspi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+};
+
+/* Verdin ETH_1 (on-module PHY) */
+&eqos {
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&reg_module_eth1phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>, <&pinctrl_eth_tpm_int>;
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ eee-broken-100tx;
+ eee-broken-1000t;
+ interrupt-parent = <&gpio1>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+/* Verdin ETH_2_RGMII */
+&fec {
+ fsl,magic-packet;
+ phy-handle = <&ethphy1>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec>;
+ pinctrl-1 = <&pinctrl_fec_sleep>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ interrupt-parent = <&gpio4>;
+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+/* Verdin CAN_1 */
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+
+/* Verdin CAN_2 */
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "disabled";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+#if 0
+ flash0: mt25qu256aba@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,mt25qu256aba";
+ reg = <0>;
+ spi-max-frequency = <80000000>;
+ spi-nor,ddr-quad-read-dummy = <6>;
+ };
+#endif
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_206",
+ "SODIMM_208",
+ "",
+ "",
+ "",
+ "SODIMM_210",
+ "SODIMM_212",
+ "SODIMM_216",
+ "SODIMM_218",
+ "",
+ "",
+ "SODIMM_16",
+ "SODIMM_155",
+ "SODIMM_157",
+ "SODIMM_185",
+ "SODIMM_91";
+};
+
+&gpio2 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_143",
+ "SODIMM_141",
+ "",
+ "",
+ "SODIMM_161",
+ "",
+ "SODIMM_84",
+ "SODIMM_78",
+ "SODIMM_74",
+ "SODIMM_80",
+ "SODIMM_82",
+ "SODIMM_70",
+ "SODIMM_72";
+
+ ctrl_sleep_moci {
+ gpio-hog;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpios = <29 GPIO_ACTIVE_HIGH>;
+ line-name = "CTRL_SLEEP_MOCI#";
+ output-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+ };
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_52",
+ "SODIMM_54",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_56",
+ "SODIMM_58",
+ "SODIMM_60",
+ "SODIMM_62",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_66",
+ "",
+ "SODIMM_64",
+ "",
+ "",
+ "SODIMM_34",
+ "SODIMM_19",
+ "",
+ "SODIMM_32",
+ "",
+ "",
+ "SODIMM_30",
+ "SODIMM_59",
+ "SODIMM_57",
+ "SODIMM_63",
+ "SODIMM_61";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_252",
+ "SODIMM_222",
+ "SODIMM_36",
+ "SODIMM_220",
+ "SODIMM_193",
+ "SODIMM_191",
+ "SODIMM_201",
+ "SODIMM_203",
+ "SODIMM_205",
+ "SODIMM_207",
+ "SODIMM_199",
+ "SODIMM_197",
+ "SODIMM_221",
+ "SODIMM_219",
+ "SODIMM_217",
+ "SODIMM_215",
+ "SODIMM_211",
+ "SODIMM_213",
+ "SODIMM_189",
+ "SODIMM_244",
+ "SODIMM_38",
+ "",
+ "SODIMM_76",
+ "SODIMM_135",
+ "SODIMM_133",
+ "SODIMM_17",
+ "SODIMM_24",
+ "SODIMM_26",
+ "SODIMM_21",
+ "SODIMM_256",
+ "SODIMM_48",
+ "SODIMM_44";
+};
+
+/* On-module I2C */
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ pmic: pca9450@25 {
+ compatible = "nxp,pca9450";
+ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ i2c-lt-en = <0x101>;
+ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0x25>;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pca9450,pmic-buck2-uses-i2c-dvs;
+ /* Run/Standby voltage */
+ pca9450,pmic-buck2-dvs-voltage = <950000>, <850000>;
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +VDD_SOC (buck1)";
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +VDD_ARM (buck2)";
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck4_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "buck4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +V3.3 (buck4)";
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +V1.8 (buck5)";
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +VDD_DDR (buck6)";
+ };
+
+ ldo1_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +V1.8_SNVS (ldo1)";
+ };
+
+ ldo2_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +V0.8_SNVS (ldo2)";
+ };
+
+ ldo3_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "On-module +V1.8A (ldo3)";
+ };
+
+ ldo4_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-name = "On-module +V3.3_ADC (ldo4)";
+ };
+
+ ldo5_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name =
+ "On-module +V3.3_1.8_SD (ldo5)";
+ };
+ };
+ };
+
+ rtc_i2c: rtc@32 {
+ compatible = "epson,rx8130";
+ reg = <0x32>;
+ };
+
+ /* On-module temperature sensor */
+ hwmon_temp_module: sensor@48 {
+ compatible = "ti,tmp1075";
+ reg = <0x48>;
+ };
+
+ adc@49 {
+ compatible = "ti,ads1015";
+ reg = <0x49>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Verdin I2C_1 (ADC_4 - ADC_3) */
+ channel@0 {
+ reg = <0>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_4 - ADC_1) */
+ channel@1 {
+ reg = <1>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_3 - ADC_1) */
+ channel@2 {
+ reg = <2>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 (ADC_2 - ADC_1) */
+ channel@3 {
+ reg = <3>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_4 */
+ channel@4 {
+ reg = <4>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_3 */
+ channel@5 {
+ reg = <5>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_2 */
+ channel@6 {
+ reg = <6>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+
+ /* Verdin I2C_1 ADC_1 */
+ channel@7 {
+ reg = <7>;
+ ti,gain = <2>;
+ ti,datarate = <4>;
+ };
+ };
+
+ eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ clock-frequency = <10000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+
+ atmel_mxt_ts_mezzanine: touch-mezzanine@4a {
+ compatible = "atmel,maxtouch";
+ /* Verdin GPIO_3 (SODIMM 210) */
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x4a>;
+ /* Verdin GPIO_2 (SODIMM 208) */
+ reset-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+};
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+ gpio_expander_21: gpio-expander@21 {
+ compatible = "nxp,pcal6416";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x21>;
+ status = "disabled";
+ };
+
+ lvds_ti_sn65dsi83: bridge@2c {
+ compatible = "ti,sn65dsi83";
+ /* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ enable-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+ reg = <0x2c>;
+ status = "disabled";
+ };
+
+ /* Current measurement into module VCC */
+ hwmon: hwmon@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ status = "disabled";
+ };
+
+ hdmi_lontium_lt8912: hdmi@48 {
+ compatible = "lontium,lt8912";
+ ddc-i2c-bus = <&i2c2>;
+ /* Verdin PWM_3_DSI (SODIMM 19) */
+ hpd-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+ reg = <0x48>;
+ /* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+ };
+
+ atmel_mxt_ts: touch@4a {
+ compatible = "atmel,maxtouch";
+ /* Verdin GPIO_9_DSI (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused */
+ interrupt-parent = <&gpio4>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+ reg = <0x4a>;
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+ reset-gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ /* temperature sensor on carrier board */
+ hwmon_temp: hwmontemp@4f {
+ compatible = "ti,tmp75c";
+ reg = <0x4f>;
+ status = "disabled";
+ };
+
+ /* EEPROM on display adapter (MIPI DSI Display Adapter) */
+ eeprom_display_adapter: eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ status = "disabled";
+ };
+
+ /* EEPROM on carrier board */
+ eeprom_carrier_board: eeprom@57 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x57>;
+ status = "disabled";
+ };
+};
+
+&ldb {
+ status = "disabled";
+
+ lvds_channel0: lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds_out: endpoint {
+ remote-endpoint = <&panel_lvds_in>;
+ };
+ };
+ };
+};
+
+&mu {
+ status = "okay";
+};
+
+/* Verdin PCIE_1 */
+&pcie {
+ bus-range = <0x00 0xff>;
+ clocks = <&clk IMX8MP_CLK_HSIO_AXI_DIV>,
+ <&clk IMX8MP_CLK_PCIE_AUX>,
+ <&clk IMX8MP_CLK_PCIE_PHY>,
+ <&clk IMX8MP_CLK_PCIE_ROOT>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI_SRC>,
+ <&clk IMX8MP_CLK_PCIE_AUX>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+ <&clk IMX8MP_SYS_PLL2_50M>;
+ ext_osc = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reserved-region = <&rpmsg_reserved>;
+ /* PCIE_1_RESET# (SODIMM 244) */
+ reset-gpio = <&gpio4 19 GPIO_ACTIVE_LOW>;
+};
+
+&pcie_phy {
+ ext_osc = <0>;
+};
+
+/* Verdin PWM_1 */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_1>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_2>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_3_DSI */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_3>;
+ #pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai1 {
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI1>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_IPG>, <&clk IMX8MP_CLK_DUMMY>,
+ <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1>, <&clk IMX8MP_CLK_DUMMY>,
+ <&clk IMX8MP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ fsl,sai-mclk-direction-output;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+};
+
+/* VERDIN I2S_2 */
+&sai3 {
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>,
+ <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>, <&clk IMX8MP_CLK_DUMMY>,
+ <&clk IMX8MP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ fsl,sai-mclk-direction-output;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+};
+
+&sdma2 {
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ fsl,uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+};
+
+/* Verdin UART_3, used as the Linux Console */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+};
+
+/* Verdin UART_4, used for Bluetooth on Wi-Fi/Bluetooth SKUs */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+};
+
+/* Verdin USB_1 */
+&usb3_phy0 {
+ fsl,phy-comp-dis-tune = <7>;
+ fsl,phy-pcs-tx-swing-full = <0x7f>;
+ fsl,pcs-tx-deemph-3p5db = <0x21>;
+ fsl,phy-tx-preemp-amp-tune = <3>;
+ fsl,phy-tx-rise-tune = <0>;
+ fsl,phy-tx-vref-tune = <6>;
+};
+
+&usb_dwc3_0 {
+ extcon = <&extcon_usb_1_id>;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1_en>;
+};
+
+/* Verdin USB_2 */
+&usb3_phy1 {
+ fsl,phy-tx-preemp-amp-tune = <2>;
+};
+
+&usb_dwc3_1 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2_en>;
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+/* On-module eMMC */
+&usdhc3 {
+ bus-width = <8>;
+ keep-power-in-suspend;
+ mmc-hs400-1_8v;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ pm-ignore-notify;
+ status = "okay";
+ vqmmc-supply = <&buck5_reg>;
+ vmmc-supply = <&buck4_reg>;
+};
+
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_vc8000e {
+ status = "okay";
+};
+
+&wdog1 {
+ fsl,ext-reset-output;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_bt_uart: btuartgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DCE_RX 0x1c4
+ MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DCE_TX 0x1c4
+ MX8MP_IOMUXC_ECSPI2_MISO__UART4_DCE_CTS 0x1c4
+ MX8MP_IOMUXC_ECSPI2_SS0__UART4_DCE_RTS 0x1c4
+ >;
+ };
+
+ pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x1c4 /* SODIMM 256 */
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK 0x4 /* SODIMM 196 */
+ MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI 0x4 /* SODIMM 200 */
+ MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO 0x1c4 /* SODIMM 198 */
+ MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x1c4 /* SODIMM 202 */
+ >;
+ };
+
+ /* Connection On Board PHY */
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3
+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3
+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91
+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91
+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91
+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91
+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91
+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91
+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f
+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f
+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f
+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f
+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f
+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f
+ >;
+ };
+
+ /* ETH_INT# shared with TPM_INT# (usually N/A) */
+ pinctrl_eth_tpm_int: ethtpmintgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x1c4
+ >;
+ };
+
+ /* Connection Carrier Board PHY ETH_2 */
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 /* SODIMM 193 */
+ MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 /* SODIMM 191 */
+ MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 /* SODIMM 201 */
+ MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 /* SODIMM 203 */
+ MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 /* SODIMM 205 */
+ MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 /* SODIMM 207 */
+ MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 /* SODIMM 197 */
+ MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 /* SODIMM 199 */
+ MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f /* SODIMM 221 */
+ MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f /* SODIMM 219 */
+ MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f /* SODIMM 217 */
+ MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f /* SODIMM 215 */
+ MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f /* SODIMM 211 */
+ MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f /* SODIMM 213 */
+ MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x1c4 /* SODIMM 189 */
+ >;
+ };
+
+ pinctrl_fec_sleep: fecsleepgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 /* SODIMM 193 */
+ MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 /* SODIMM 191 */
+ MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 /* SODIMM 201 */
+ MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 /* SODIMM 203 */
+ MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 /* SODIMM 205 */
+ MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 /* SODIMM 207 */
+ MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 /* SODIMM 197 */
+ MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 /* SODIMM 199 */
+ MX8MP_IOMUXC_SAI1_TXD0__GPIO4_IO12 0x1f /* SODIMM 221 */
+ MX8MP_IOMUXC_SAI1_TXD1__GPIO4_IO13 0x1f /* SODIMM 219 */
+ MX8MP_IOMUXC_SAI1_TXD2__GPIO4_IO14 0x1f /* SODIMM 217 */
+ MX8MP_IOMUXC_SAI1_TXD3__GPIO4_IO15 0x1f /* SODIMM 215 */
+ MX8MP_IOMUXC_SAI1_TXD4__GPIO4_IO16 0x1f /* SODIMM 211 */
+ MX8MP_IOMUXC_SAI1_TXD5__GPIO4_IO17 0x1f /* SODIMM 213 */
+ MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x184 /* SODIMM 189 */
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x154 /* SODIMM 22 */
+ MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x154 /* SODIMM 20 */
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_MCLK__CAN2_RX 0x154 /* SODIMM 26 */
+ MX8MP_IOMUXC_SAI2_TXD0__CAN2_TX 0x154 /* SODIMM 24 */
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x1c2 /* SODIMM 52 */
+ MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x82 /* SODIMM 54 */
+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x82 /* SODIMM 64 */
+ MX8MP_IOMUXC_NAND_DQS__FLEXSPI_A_DQS 0x82 /* SODIMM 66 */
+ MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x82 /* SODIMM 56 */
+ MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x82 /* SODIMM 58 */
+ MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x82 /* SODIMM 60 */
+ MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x82 /* SODIMM 62 */
+ >;
+ };
+
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00 0x184 /* SODIMM 206 */
+ >;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01 0x1c4 /* SODIMM 208 */
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x184 /* SODIMM 210 */
+ >;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x184 /* SODIMM 212 */
+ >;
+ };
+
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x184 /* SODIMM 216 */
+ >;
+ };
+
+ pinctrl_gpio6: gpio6grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO08__GPIO1_IO08 0x184 /* SODIMM 218 */
+ >;
+ };
+
+ pinctrl_gpio7: gpio7grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03 0x184 /* SODIMM 220 */
+ >;
+ };
+
+ pinctrl_gpio8: gpio8grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXC__GPIO4_IO01 0x184 /* SODIMM 222 */
+ >;
+ };
+
+ /* Verdin GPIO_9_DSI (pulled-up as active-low) */
+ pinctrl_gpio_9_dsi: gpio9dsigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x1c4 /* SODIMM 17 */
+ >;
+ };
+
+ /* Verdin GPIO_10_DSI */
+ pinctrl_gpio_10_dsi: gpio10dsigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x1c4 /* SODIMM 21 */
+ >;
+ };
+
+ /* Non-wifi MSP usage only */
+ pinctrl_gpio_hog1: gpiohog1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12 0x1c4 /* SODIMM 116 */
+ MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11 0x1c4 /* SODIMM 152 */
+ MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10 0x1c4 /* SODIMM 164 */
+ MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x1c4 /* SODIMM 128 */
+ >;
+ };
+
+ /* USB_2_OC# */
+ pinctrl_gpio_hog2: gpiohog2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x1c4 /* SODIMM 187 */
+ >;
+ };
+
+ pinctrl_gpio_hog3: gpiohog3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x1c4 /* SODIMM 157 */
+ /* CSI_1_MCLK */
+ MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x1c4 /* SODIMM 91 */
+ >;
+ };
+
+ /* Wifi usage only */
+ pinctrl_gpio_hog4: gpiohog4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART4_RXD__GPIO5_IO28 0x1c4 /* SODIMM 151 */
+ MX8MP_IOMUXC_UART4_TXD__GPIO5_IO29 0x1c4 /* SODIMM 153 */
+ >;
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXFS__GPIO4_IO00 0x1c4 /* SODIMM 252 */
+ >;
+ };
+
+ pinctrl_hdmi_hog: hdmihoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000019 /* SODIMM 63 */
+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c3 /* SODIMM 59 */
+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c3 /* SODIMM 57 */
+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000019 /* SODIMM 61 */
+ >;
+ };
+
+ /* On-module I2C */
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c6 /* PMIC_I2C_SCL */
+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c6 /* PMIC_I2C_SDA */
+ >;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x400001c6 /* PMIC_I2C_SCL */
+ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x400001c6 /* PMIC_I2C_SDA */
+ >;
+ };
+
+ /* Verdin I2C_2_DSI */
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c6 /* SODIMM 55 */
+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c6 /* SODIMM 53 */
+ >;
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x400001c6 /* SODIMM 55 */
+ MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x400001c6 /* SODIMM 53 */
+ >;
+ };
+
+ /* Verdin I2C_4_CSI */
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c6 /* SODIMM 95 */
+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c6 /* SODIMM 93 */
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x400001c6 /* SODIMM 95 */
+ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c6 /* SODIMM 93 */
+ >;
+ };
+
+ /* Verdin I2C_1 */
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c6 /* SODIMM 14 */
+ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c6 /* SODIMM 12 */
+ >;
+ };
+
+ pinctrl_i2c4_gpio: i2c4gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x400001c6 /* SODIMM 14 */
+ MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x400001c6 /* SODIMM 12 */
+ >;
+ };
+
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+ pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x184 /* SODIMM 42 */
+ >;
+ };
+
+ /* Verdin I2S_2_D_OUT shared with SAI3 */
+ pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x184 /* SODIMM 46 */
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x4 /* SODIMM 244 */
+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x1c4 /* PMIC_EN_PCIe_CLK, unused */
+ >;
+ };
+
+ pinctrl_pmic: pmicirqgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x1c4 /* PMIC_INT# */
+ >;
+ };
+
+ pinctrl_pwm_1: pwm1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SPDIF_EXT_CLK__PWM1_OUT 0x6 /* SODIMM 15 */
+ >;
+ };
+
+ pinctrl_pwm_2: pwm2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO11__PWM2_OUT 0x6 /* SODIMM 16 */
+ >;
+ };
+
+ /* Verdin PWM_3_DSI shared with GPIO3_IO20 */
+ pinctrl_pwm_3: pwm3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXC__PWM3_OUT 0x6 /* SODIMM 19 */
+ >;
+ };
+
+ /* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM3_OUT */
+ pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsi1hpdgpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x184 /* SODIMM 19 */
+ >;
+ };
+
+ pinctrl_reg_eth: regethgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_WP__GPIO2_IO20 0x184 /* PMIC_EN_ETH */
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_SYNC 0x1d6 /* SODIMM 32 */
+ MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI1_TX_BCLK 0x1d6 /* SODIMM 30 */
+ MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI1_MCLK 0x96 /* SODIMM 38 */
+ MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_RX_DATA00 0x1d6 /* SODIMM 36 */
+ MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI1_TX_DATA00 0x96 /* SODIMM 34 */
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0x1d6 /* SODIMM 48 */
+ MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0x1d6 /* SODIMM 44 */
+ MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0x1d6 /* SODIMM 42 */
+ MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0x96 /* SODIMM 46 */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x1c4 /* SODIMM 129 */
+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x1c4 /* SODIMM 131 */
+ MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS 0x1c4 /* SODIMM 133 */
+ MX8MP_IOMUXC_SAI2_RXD0__UART1_DCE_RTS 0x1c4 /* SODIMM 135 */
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x1c4 /* SODIMM 137 */
+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x1c4 /* SODIMM 139 */
+ MX8MP_IOMUXC_SD1_DATA5__UART2_DCE_CTS 0x1c4 /* SODIMM 141 */
+ MX8MP_IOMUXC_SD1_DATA4__UART2_DCE_RTS 0x1c4 /* SODIMM 143 */
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x1c4 /* SODIMM 147 */
+ MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x1c4 /* SODIMM 149 */
+ >;
+ };
+
+ /* Non-wifi usage only */
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x1c4 /* SODIMM 151 */
+ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x1c4 /* SODIMM 153 */
+ >;
+ };
+
+ pinctrl_usb1_en: usb1engrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO12__USB1_PWR 0x184 /* SODIMM 155 */
+ >;
+ };
+
+ /* USB_1_ID */
+ pinctrl_usb_1_id: usb1idgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x1c4 /* SODIMM 161 */
+ >;
+ };
+
+ pinctrl_usb2_en: usb2engrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO14__USB2_PWR 0x184 /* SODIMM 185 */
+ >;
+ };
+
+ /* On-module Wi-Fi/BT */
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp-100mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x194
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d4
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d4
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d4
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d4
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp-200mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x196
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d6
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d6
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d6
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d6
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc2_cd: usdhc2cdgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4 /* SODIMM 84 */
+ >;
+ };
+
+ pinctrl_usdhc2_cd_sleep: usdhc2cdslpgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x0 /* SODIMM 84 */
+ >;
+ };
+
+ pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x4 /* SODIMM 76 */
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 /* SODIMM 78 */
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0 /* SODIMM 74 */
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 /* SODIMM 80 */
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 /* SODIMM 82 */
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 /* SODIMM 70 */
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 /* SODIMM 72 */
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x4 /* PMIC_USDHC_VSELECT */
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp-100mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x4
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp-200mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x4
+ >;
+ };
+
+ /* Avoid backfeeding with removed card power */
+ pinctrl_usdhc2_sleep: usdhc2slpgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x100
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x100
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x100
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x100
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x100
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x100
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190
+ MX8MP_IOMUXC_GPIO1_IO09__USDHC3_RESET_B 0x1d1
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194
+ MX8MP_IOMUXC_GPIO1_IO09__USDHC3_RESET_B 0x1d1
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196
+ MX8MP_IOMUXC_GPIO1_IO09__USDHC3_RESET_B 0x1d1
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x1c4 /* PMIC_WDI */
+ >;
+ };
+
+ pinctrl_bluetooth_ctrl: bluetoothctrlgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x1c4 /* WIFI_WKUP_BT */
+ >;
+ };
+
+ pinctrl_wifi_ctrl: wifictrlgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0x1c4 /* WIFI_WKUP_WLAN */
+ >;
+ };
+
+ pinctrl_wifi_i2s: wifii2sgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXD2__GPIO3_IO23 0x1d6 /* WIFI_TX_BCLK */
+ MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x96 /* WIFI_RX_DATA0 */
+ MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x1d6 /* WIFI_TX_SYNC */
+ MX8MP_IOMUXC_SAI5_RXD3__GPIO3_IO24 0x1d6 /* WIFI_TX_DATA0 */
+ >;
+ };
+
+ pinctrl_wifi_pwr_en: wifipwrengrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x184 /* PMIC_EN_WIFI */
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 29252cf0a655..34ebc97e144d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1173,7 +1173,7 @@
ranges;
sai1: sai@30c10000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c10000 0x10000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI1_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1189,7 +1189,7 @@
};
sai2: sai@30c20000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c20000 0x10000>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI2_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1205,7 +1205,7 @@
};
sai3: sai@30c30000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c30000 0x10000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1221,7 +1221,7 @@
};
sai5: sai@30c50000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c50000 0x10000>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI5_IPG>, <&clk IMX8MP_CLK_DUMMY>,
@@ -1237,7 +1237,7 @@
};
sai6: sai@30c60000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c60000 0x10000>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI6_IPG>,
@@ -1254,7 +1254,7 @@
};
sai7: sai@30c80000 {
- compatible = "fsl,imx8mq-sai", "fsl,imx6sx-sai";
+ compatible = "fsl,imx8mp-sai", "fsl,imx6sx-sai";
reg = <0x30c80000 0x10000>;
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI7_IPG>, <&clk IMX8MP_CLK_DUMMY>,
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts
new file mode 100644
index 000000000000..ebff51c16c03
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis.dtsi"
+#include "imx8-apalis-eval.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM/QP on Apalis Evaluation Board";
+ compatible = "toradex,apalis-imx8-eval",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-ixora-v1.1.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-ixora-v1.1.dts
new file mode 100644
index 000000000000..91bc4435fb49
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-ixora-v1.1.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis.dtsi"
+#include "imx8-apalis-ixora-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM/QP on Apalis Ixora V1.1 Carrier Board";
+ compatible = "toradex,apalis-imx8qp-ixora-v1.1",
+ "toradex,apalis-imx8-ixora-v1.1",
+ "toradex,apalis-imx8qp-ixora",
+ "toradex,apalis-imx8-ixora",
+ "toradex,apalis-imx8qp",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts
new file mode 100644
index 000000000000..6589cdb2251b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis-v1.1.dtsi"
+#include "imx8-apalis-eval.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM V1.1 on Apalis Evaluation Board";
+ compatible = "toradex,apalis-imx8-v1.1-eval",
+ "toradex,apalis-imx8-eval",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.1.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.1.dts
new file mode 100644
index 000000000000..579a27fb5662
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.1.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019-2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis-v1.1.dtsi"
+#include "imx8-apalis-ixora-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM V1.1 on Apalis Ixora V1.1 Carrier Board";
+ compatible = "toradex,apalis-imx8-v1.1-ixora-v1.1",
+ "toradex,apalis-imx8-v1.1-ixora",
+ "toradex,apalis-imx8-v1.1",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.2.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.2.dts
new file mode 100644
index 000000000000..9e61c7aaa69e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-ixora-v1.2.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis-v1.1.dtsi"
+#include "imx8-apalis-ixora-v1.2.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM V1.1 on Apalis Ixora V1.2 Carrier Board";
+ compatible = "toradex,apalis-imx8qm-ixora-v1.2",
+ "toradex,apalis-imx8-ixora-v1.2",
+ "toradex,apalis-imx8qm-ixora",
+ "toradex,apalis-imx8-ixora",
+ "toradex,apalis-imx8qm",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi
new file mode 100644
index 000000000000..65188f479d03
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+#include "imx8qm.dtsi"
+#include "imx8-apalis-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM V1.1";
+ compatible = "toradex,apalis-imx8-v1.1",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
+
+&cooling_maps_map0 {
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A72_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi
new file mode 100644
index 000000000000..84262cd19125
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2017-2020 Toradex
+ */
+
+#include "imx8qm-apalis-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM";
+ compatible = "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
+
+/delete-node/ &pcie_wifi_refclk_gate;
+
+&ethphy0 {
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+};
+
+/*
+ * Apalis iMX8QM V1.0 has PHY KSZ9031. the Micrel PHY driver
+ * doesn't support setting internal PHY delay for TXC line for
+ * this PHY model. Use delay on MAC side instead.
+ */
+&fec1 {
+ fsl,rgmii_txc_dly;
+ phy-mode = "rgmii-rxid";
+};
+
+&lsio_gpio0 {
+ gpio-line-names = "MXM3_279",
+ "MXM3_277",
+ "MXM3_135",
+ "MXM3_203",
+ "MXM3_201",
+ "MXM3_275",
+ "MXM3_110",
+ "MXM3_120",
+ "MXM3_1/GPIO1",
+ "MXM3_3/GPIO2",
+ "MXM3_124",
+ "MXM3_122",
+ "MXM3_5/GPIO3",
+ "MXM3_7/GPIO4",
+ "",
+ "",
+ "MXM3_4",
+ "MXM3_211",
+ "MXM3_209",
+ "MXM3_2",
+ "MXM3_136",
+ "MXM3_134",
+ "MXM3_6",
+ "MXM3_8",
+ "MXM3_112",
+ "MXM3_118",
+ "MXM3_114",
+ "MXM3_116";
+};
+
+&lsio_gpio1 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "MXM3_286",
+ "",
+ "MXM3_87",
+ "MXM3_99",
+ "MXM3_138",
+ "MXM3_140",
+ "MXM3_239",
+ "",
+ "MXM3_281",
+ "MXM3_283",
+ "MXM3_126",
+ "MXM3_132",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_173",
+ "MXM3_175",
+ "MXM3_123";
+};
+
+&lsio_gpio2 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_198",
+ "MXM3_35",
+ "MXM3_164",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_217",
+ "MXM3_215",
+ "",
+ "",
+ "MXM3_193",
+ "MXM3_194",
+ "MXM3_37",
+ "",
+ "MXM3_271",
+ "MXM3_273",
+ "MXM3_195",
+ "MXM3_197",
+ "MXM3_177",
+ "MXM3_179",
+ "MXM3_181",
+ "MXM3_183",
+ "MXM3_185",
+ "MXM3_187";
+};
+
+&lsio_gpio3 {
+ gpio-line-names = "MXM3_191",
+ "",
+ "MXM3_221",
+ "MXM3_225",
+ "MXM3_223",
+ "MXM3_227",
+ "MXM3_200",
+ "MXM3_235",
+ "MXM3_231",
+ "MXM3_229",
+ "MXM3_233",
+ "MXM3_204",
+ "MXM3_196",
+ "",
+ "MXM3_202",
+ "",
+ "",
+ "",
+ "MXM3_305",
+ "MXM3_307",
+ "MXM3_309",
+ "MXM3_311",
+ "MXM3_315",
+ "MXM3_317",
+ "MXM3_319",
+ "MXM3_321",
+ "MXM3_15/GPIO7",
+ "MXM3_63",
+ "MXM3_17/GPIO8",
+ "MXM3_12",
+ "MXM3_14",
+ "MXM3_16";
+};
+
+&lsio_gpio4 {
+ gpio-line-names = "MXM3_18",
+ "MXM3_11/GPIO5",
+ "MXM3_13/GPIO6",
+ "MXM3_274",
+ "MXM3_84",
+ "MXM3_262",
+ "MXM3_96",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_190",
+ "",
+ "",
+ "",
+ "MXM3_269",
+ "MXM3_251",
+ "MXM3_253",
+ "MXM3_295",
+ "MXM3_299",
+ "MXM3_301",
+ "MXM3_297",
+ "MXM3_293",
+ "MXM3_291",
+ "MXM3_289",
+ "MXM3_287";
+};
+
+&lsio_gpio5 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_150",
+ "MXM3_160",
+ "MXM3_162",
+ "MXM3_144",
+ "MXM3_146",
+ "MXM3_148",
+ "MXM3_152",
+ "MXM3_156",
+ "MXM3_158",
+ "MXM3_159",
+ "MXM3_184",
+ "MXM3_180",
+ "MXM3_186",
+ "MXM3_188",
+ "MXM3_176",
+ "MXM3_178";
+};
+
+&lsio_gpio6 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "MXM3_261",
+ "MXM3_263",
+ "MXM3_259",
+ "MXM3_257",
+ "MXM3_255",
+ "MXM3_128",
+ "MXM3_130",
+ "MXM3_265",
+ "MXM3_249",
+ "MXM3_247",
+ "MXM3_245",
+ "MXM3_243";
+};
+
+/* Apalis I2C2 (DDC) */
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c0>;
+};
+
+&pinctrl_fec1 {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0 /* Use pads in 1.8V mode */
+ IMX8QM_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ IMX8QM_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ IMX8QM_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x06000020
+ IMX8QM_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x06000020
+ IMX8QM_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x06000020
+ IMX8QM_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x06000020
+ IMX8QM_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x06000020
+ IMX8QM_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x06000020
+ IMX8QM_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x06000020
+ IMX8QM_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x06000020
+ IMX8QM_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x06000020
+ IMX8QM_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x06000020
+ IMX8QM_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x06000020
+ IMX8QM_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x06000020
+ IMX8QM_ENET0_REFCLK_125M_25M_CONN_ENET0_REFCLK_125M_25M 0x06000020
+ /* On-module ETH_RESET# */
+ IMX8QM_LVDS1_GPIO01_LSIO_GPIO1_IO11 0x06000020
+ /* On-module ETH_INT# */
+ IMX8QM_LVDS0_GPIO01_LSIO_GPIO1_IO05 0x04000060
+ >;
+};
+
+&pinctrl_fec1_sleep {
+ fsl,pins = <
+ IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0
+ IMX8QM_ENET0_MDC_LSIO_GPIO4_IO14 0x04000040
+ IMX8QM_ENET0_MDIO_LSIO_GPIO4_IO13 0x04000040
+ IMX8QM_ENET0_RGMII_TX_CTL_LSIO_GPIO5_IO31 0x04000040
+ IMX8QM_ENET0_RGMII_TXC_LSIO_GPIO5_IO30 0x04000040
+ IMX8QM_ENET0_RGMII_TXD0_LSIO_GPIO6_IO00 0x04000040
+ IMX8QM_ENET0_RGMII_TXD1_LSIO_GPIO6_IO01 0x04000040
+ IMX8QM_ENET0_RGMII_TXD2_LSIO_GPIO6_IO02 0x04000040
+ IMX8QM_ENET0_RGMII_TXD3_LSIO_GPIO6_IO03 0x04000040
+ IMX8QM_ENET0_RGMII_RXC_LSIO_GPIO6_IO04 0x04000040
+ IMX8QM_ENET0_RGMII_RX_CTL_LSIO_GPIO6_IO05 0x04000040
+ IMX8QM_ENET0_RGMII_RXD0_LSIO_GPIO6_IO06 0x04000040
+ IMX8QM_ENET0_RGMII_RXD1_LSIO_GPIO6_IO07 0x04000040
+ IMX8QM_ENET0_RGMII_RXD2_LSIO_GPIO6_IO08 0x04000040
+ IMX8QM_ENET0_RGMII_RXD3_LSIO_GPIO6_IO09 0x04000040
+ IMX8QM_ENET0_REFCLK_125M_25M_LSIO_GPIO4_IO15 0x04000040
+ IMX8QM_LVDS1_GPIO01_LSIO_GPIO1_IO11 0x04000040
+ IMX8QM_LVDS0_GPIO01_LSIO_GPIO1_IO05 0x04000040
+ >;
+};
+
+&iomuxc {
+ apalis-imx8qm {
+ /* Apalis I2C2 (DDC) */
+ pinctrl_lpi2c0: lpi2c0grp {
+ fsl,pins = <
+ IMX8QM_HDMI_TX0_TS_SCL_DMA_I2C0_SCL 0x04000022
+ IMX8QM_HDMI_TX0_TS_SDA_DMA_I2C0_SDA 0x04000022
+ >;
+ };
+ };
+};
+
+/* On-module PCIe_CTRL0_CLKREQ */
+&pinctrl_pcie_sata_refclk {
+ fsl,pins = <
+ IMX8QM_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO27 0x00000021
+ >;
+};
+
+&pcie_sata_refclk_gate {
+ enable-gpios = <&lsio_gpio4 27 GPIO_ACTIVE_HIGH>;
+};
+
+/* On-module Wi-Fi */
+&pcieb {
+ clocks = <&pcieb_lpcg 0>,
+ <&pcieb_lpcg 1>,
+ <&pcieb_lpcg 2>,
+ <&phyx2_lpcg 1>,
+ <&phyx2_lpcg 0>,
+ <&phyx2_crr0_lpcg 0>,
+ <&pcieb_crr3_lpcg 0>,
+ <&pciea_crr2_lpcg 0>,
+ <&misc_crr5_lpcg 0>,
+ <&pcie_sata_refclk_gate>;
+ clock-names = "pcie", "pcie_bus", "pcie_inbound_axi",
+ "pcie_phy", "pcie_phy_pclk", "phy_per",
+ "pcie_per", "pciex2_per", "misc_per",
+ "pcie_ext";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ /*
+ * The PMIC on V1.0A HW generates 1.6V instead of 1.8V which creates
+ * issues with certain SD cards, disable 1.8V signaling for now.
+ */
+ no-1-8-v;
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ /*
+ * The PMIC on V1.0A HW generates 1.6V instead of 1.8V which creates
+ * issues with certain SD cards, disable 1.8V signaling for now.
+ */
+ no-1-8-v;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-eval.dts b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-eval.dts
new file mode 100644
index 000000000000..80de879b15a1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-eval.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qp-apalis-v1.1.dtsi"
+#include "imx8-apalis-eval.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QP V1.1 on Apalis Evaluation Board";
+ compatible = "toradex,apalis-imx8qp-v1.1-eval",
+ "toradex,apalis-imx8qp-v1.1",
+ "toradex,apalis-imx8-v1.1",
+ "toradex,apalis-imx8",
+ "fsl,imx8qp",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.1.dts b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.1.dts
new file mode 100644
index 000000000000..b57e9caccb42
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.1.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qp-apalis-v1.1.dtsi"
+#include "imx8-apalis-ixora-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QP V1.1 on Apalis Ixora V1.1 Carrier Board";
+ compatible = "toradex,apalis-imx8qp-v1.1-ixora-v1.1",
+ "toradex,apalis-imx8qp-v1.1-ixora",
+ "toradex,apalis-imx8qp-v1.1",
+ "toradex,apalis-imx8-v1.1",
+ "toradex,apalis-imx8",
+ "fsl,imx8qp",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.2.dts b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.2.dts
new file mode 100644
index 000000000000..8ec876302ab2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1-ixora-v1.2.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qp-apalis-v1.1.dtsi"
+#include "imx8-apalis-ixora-v1.2.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QP V1.1 on Apalis Ixora V1.2 Carrier Board";
+ compatible = "toradex,apalis-imx8qp-v1.1-ixora-v1.2",
+ "toradex,apalis-imx8qp-v1.1-ixora",
+ "toradex,apalis-imx8qp-v1.1",
+ "toradex,apalis-imx8-v1.1",
+ "toradex,apalis-imx8",
+ "fsl,imx8qp",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1.dtsi
new file mode 100644
index 000000000000..b40a9a4425c3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qp-apalis-v1.1.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2020 Toradex
+ */
+
+#include "imx8qp.dtsi"
+#include "imx8-apalis-v1.1.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QP V1.1";
+ compatible = "toradex,apalis-imx8qp-v1.1",
+ "toradex,apalis-imx8qp",
+ "toradex,apalis-imx8",
+ "fsl,imx8qp",
+ "fsl,imx8qm";
+};
+
+&cooling_maps_map0 {
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-aster.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-aster.dts
new file mode 100644
index 000000000000..929b9d6a470b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-aster.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+#include "imx8x-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP on Aster Board";
+ compatible = "toradex,colibri-imx8x-aster",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts
new file mode 100644
index 000000000000..710539a83394
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+#include "imx8x-colibri-eval-v3.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri-imx8x-eval-v3",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris-v2.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris-v2.dts
new file mode 100644
index 000000000000..39a3a54661c3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris-v2.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+#include "imx8x-colibri-iris-v2.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP on Colibri Iris V2 Board";
+ compatible = "toradex,colibri-imx8x-iris-v2",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris.dts
new file mode 100644
index 000000000000..d1bf8ee902b4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-iris.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+#include "imx8x-colibri-iris.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP on Colibri Iris Board";
+ compatible = "toradex,colibri-imx8x-iris",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-dual-channel.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-dual-channel.dts
new file mode 100644
index 000000000000..1cd7e3038ba9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-dual-channel.dts
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP/DX on LVDS Embedded World Demo";
+ compatible = "toradex,colibri-imx8x-lvds-demo",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+ backlight = <&backlight>;
+ status = "okay";
+
+ panel-timing {
+ clock-frequency = <138500000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hback-porch = <80>;
+ hfront-porch = <48>;
+ vback-porch = <23>;
+ vfront-porch = <3>;
+ hsync-len = <32>;
+ vsync-len = <5>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ port {
+ panel_lvds_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&adma_pwm {
+ status = "okay";
+};
+
+&adma_pwm_lpcg {
+ status = "okay";
+};
+
+&backlight {
+ pinctrl-0 = <&pinctrl_gpio_hpd>;
+ enable-gpios = <&lsio_gpio1 31 GPIO_ACTIVE_HIGH>; /* Colibri BL_ON */
+ status = "okay";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+ status = "okay";
+};
+
+&ldb1 {
+ fsl,dual-channel;
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_lvds_in>;
+ };
+ };
+ };
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "disabled";
+};
+
+&ldb2_phy {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ status= "okay";
+};
+
+&mipi0_dphy {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-single-channel.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-single-channel.dts
new file mode 100644
index 000000000000..ebe216349171
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-lvds-single-channel.dts
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP/DX on LVDS Embedded World Demo";
+ compatible = "toradex,colibri-imx8x-lvds-demo",
+ "toradex,colibri-imx8x",
+ "fsl,imx8qxp";
+
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+ backlight = <&backlight>;
+ data-mapping = "vesa-24";
+ width-mm = <217>;
+ height-mm = <136>;
+
+ status = "okay";
+
+ panel-timing {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ port {
+ panel_lvds_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&adma_pwm {
+ status = "okay";
+};
+
+&adma_pwm_lpcg {
+ status = "okay";
+};
+
+&backlight {
+ pinctrl-0 = <&pinctrl_gpio_hpd>;
+ enable-gpios = <&lsio_gpio1 31 GPIO_ACTIVE_HIGH>; /* Colibri BL_ON */
+ status = "okay";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+ status = "okay";
+};
+
+&ldb1 {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_lvds_in>;
+ };
+ };
+ };
+};
+
+&ldb1_phy {
+ status = "okay";
+};
+
+&ldb2 {
+ status = "disabled";
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ status= "okay";
+};
+
+&mipi0_dphy {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi
new file mode 100644
index 000000000000..b65d9ee33cb2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8qxp.dtsi"
+#include "imx8x-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX8QXP Module";
+ compatible = "toradex,colibri-imx8x", "fsl,imx8qxp";
+};
+
+&pmic_cooling_map0 {
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri-aster.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri-aster.dtsi
new file mode 100644
index 000000000000..ad4c83d43ef8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri-aster.dtsi
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/* Colibri Ethernet */
+&fec1 {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog0>, <&pinctrl_hog2>;
+};
+
+&lpspi2 {
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&lsio_gpio1 0 GPIO_ACTIVE_LOW
+ &lsio_gpio5 2 GPIO_ACTIVE_LOW>;
+
+ spidev1: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <1>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
+/* Colibri UART_B */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ status= "okay";
+};
+
+/* Colibri SDCard */
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri-eval-v3.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri-eval-v3.dtsi
new file mode 100644
index 000000000000..2e7a9ae4da11
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri-eval-v3.dtsi
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &rtc;
+ };
+
+ /* fixed crystal dedicated to mcp25xx */
+ clk16m: clock-16mhz-fixed {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&lsio_gpio5 9 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_reg>;
+ regulator-name = "usbh_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+};
+
+/* Colibri Analogue Inputs */
+&adc0 {
+ status = "okay";
+};
+
+/* Colibri PWM_A */
+&adma_pwm {
+ status = "okay";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+ status = "okay";
+};
+
+/* Colibri I2C */
+&i2c1 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&jpegdec {
+ status = "okay";
+};
+
+&jpegenc {
+ status = "okay";
+};
+
+/* Colibri SPI */
+&lpspi2 {
+ mcp2515: can@0 {
+ compatible = "microchip,mcp2515";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_int>;
+ reg = <0>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+ };
+ /* To keep the CAN controller enabled by default,
+ * disable conflicting spidev. This spidev device
+ * enables with the devicetree overlay.
+ */
+ spidev0: spidev@0 {
+ status = "disabled";
+ };
+};
+
+/* Colibri UART_B */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ status= "okay";
+};
+
+&lsio_gpio3 {
+ /*
+ * Add GPIO3_10 as a wakeup source:
+ * Pin: 157 SC_P_QSPI0A_DATA1 (SODIMM_45)
+ * Type: 6 SC_PAD_WAKEUP_RISE_EDGE
+ * Line: 10 GPIO3_IO10
+ */
+ pad-wakeup = <IMX8QXP_QSPI0A_DATA1 6 10>;
+ pad-wakeup-num = <1>;
+ };
+
+/* Colibri PWM_B */
+&pwm0 {
+ status = "okay";
+};
+
+/* Colibri PWM_C */
+&pwm1 {
+ status = "okay";
+};
+
+/* Colibri PWM_D */
+&pwm2 {
+ status = "okay";
+};
+
+/* USB PHY for &usbotg3 */
+&usb3phynop1 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* USB PHY for &usbotg1 */
+&usbphy1 {
+ status = "okay";
+};
+
+/* Colibri SD/MMC Card */
+&usdhc2 {
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+&vpu_lpcg {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi
new file mode 100644
index 000000000000..f5c6809a81b8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "imx8x-colibri-iris.dtsi"
+
+/ {
+ reg_3v3_vmmc: regulator-3v3-vmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_vmmc>;
+ regulator-name = "3v3_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&lsio_gpio0 31 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds_converter &pinctrl_gpio_iris>;
+
+ usdhc {
+ pinctrl_enable_3v3_vmmc: enable_3v3_vmmc {
+ fsl,pins = <
+ IMX8QXP_SAI1_RXFS_LSIO_GPIO0_IO31 0x20 /* SODIMM 100 */
+ >;
+ };
+ };
+};
+
+/* Colibri SD/MMC Card */
+&usdhc2 {
+ cap-power-off-card;
+ /delete-property/ no-1-8-v;
+ vmmc-supply = <&reg_3v3_vmmc>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri-iris.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris.dtsi
new file mode 100644
index 000000000000..bd6c85fafedd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris.dtsi
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/ {
+ aliases {
+ rtc0 = &rtc_i2c;
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&lsio_gpio5 9 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_reg>;
+ regulator-name = "usbh_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+};
+
+/* Colibri Analogue Inputs */
+&adc0 {
+ status = "okay";
+};
+
+/* Colibri PWM_A */
+&adma_pwm {
+ status = "okay";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+ status = "okay";
+};
+
+/* Colibri I2C */
+&i2c1 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_iris>;
+
+ gpio {
+ pinctrl_gpio_iris: gpio-iris {
+ fsl,pins = <
+ IMX8QXP_QSPI0B_DATA3_LSIO_GPIO3_IO21 0x20 /* SODIMM 98 */
+ IMX8QXP_USB_SS3_TC1_LSIO_GPIO4_IO04 0x20 /* SODIMM 133 */
+ IMX8QXP_SAI0_TXD_LSIO_GPIO0_IO25 0x20 /* SODIMM 103 */
+ IMX8QXP_SAI0_TXFS_LSIO_GPIO0_IO28 0x20 /* SODIMM 101 */
+ IMX8QXP_SAI0_RXD_LSIO_GPIO0_IO27 0x20 /* SODIMM 97 */
+ IMX8QXP_ENET0_RGMII_RXC_LSIO_GPIO5_IO03 0x06000020 /* SODIMM 85 */
+ IMX8QXP_SAI0_TXC_LSIO_GPIO0_IO26 0x20 /* SODIMM 79 */
+ IMX8QXP_QSPI0A_DATA1_LSIO_GPIO3_IO10 0x06700041 /* SODIMM 45 */
+ >;
+ };
+ };
+
+ uart {
+ pinctrl_uart1_forceoff: uart1_forceoff {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_SS0_B_LSIO_GPIO3_IO14 0x20 /* SODIMM 22 */
+ >;
+ };
+
+ pinctrl_uart23_forceoff: uart23_forceoff {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00 0x20 /* SODIMM 23 */
+ >;
+ };
+ };
+};
+
+&jpegdec {
+ status = "okay";
+};
+
+&jpegenc {
+ status = "okay";
+};
+
+/* Colibri UART_B */
+&lpuart0 {
+ status = "okay";
+};
+
+/* Colibri UART_C */
+&lpuart2 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ status= "okay";
+};
+
+&lsio_gpio3 {
+ /*
+ * Add GPIO3_10 as a wakeup source:
+ * Pin: 157 SC_P_QSPI0A_DATA1 (SODIMM_45)
+ * Type: 6 SC_PAD_WAKEUP_RISE_EDGE
+ * Line: 10 GPIO3_IO10
+ */
+ pad-wakeup = <IMX8QXP_QSPI0A_DATA1 6 10>;
+ pad-wakeup-num = <1>;
+
+ /*
+ * This turns the LVDS transceiver on. If one wants to turn the
+ * transceiver off, that property has to be deleted and the gpio handled
+ * in userspace.
+ */
+ lvds_tx_on {
+ gpio-hog;
+ gpios = <18 0>;
+ output-high;
+ };
+};
+
+
+/* Colibri PWM_B */
+&pwm0 {
+ status = "okay";
+};
+
+/* Colibri PWM_C */
+&pwm1 {
+ status = "okay";
+};
+
+/* Colibri PWM_D */
+&pwm2 {
+ status = "okay";
+};
+
+/* USB PHY for &usbotg3 */
+&usb3phynop1 {
+ status = "okay";
+};
+
+&usbotg1 {
+ extcon = <&extcon_usbc_det &extcon_usbc_det>;
+ vbus-supply = <&reg_usbh_vbus>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* USB PHY for &usbotg1 */
+&usbphy1 {
+ status = "okay";
+};
+
+/* Colibri SD/MMC Card */
+&usdhc2 {
+ status = "okay";
+};
+
+&vpu_decoder {
+ status = "okay";
+};
+
+&vpu_encoder {
+ status = "okay";
+};
+
+&vpu_lpcg {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri.dtsi
new file mode 100644
index 000000000000..c479f219e712
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri.dtsi
@@ -0,0 +1,1474 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+
+/ {
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bl_on>;
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ enable-gpios = <&lsio_gpio3 12 GPIO_ACTIVE_HIGH>; /* Colibri BL_ON */
+ power-supply = <&reg_module_3v3>;
+ pwms = <&adma_pwm 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ chosen {
+ bootargs = "console=ttyLP3,115200";
+ stdout-path = &lpuart3;
+ };
+
+ /* Colibri Parallel RGB */
+ display_lcdif: display@disp1 {
+ compatible = "fsl,imx-lcdif-mux-display";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ clocks = <&clk IMX_SC_R_LCD_0 IMX_SC_PM_CLK_BYPASS>,
+ <&clk IMX_SC_R_LCD_0 IMX_SC_PM_CLK_MISC0>;
+ clock-names = "bypass_div", "pixel";
+ assigned-clocks = <&clk IMX_SC_R_LCD_0 IMX_SC_PM_CLK_MISC0>;
+ assigned-clock-parents = <&clk IMX_SC_R_LCD_0 IMX_SC_PM_CLK_BYPASS>;
+ fsl,lcdif-mux-regs = <&lcdif_mux_regs>;
+ fsl,interface-pix-fmt = "rgb666";
+ power-domains = <&pd IMX_SC_R_LCD_0>;
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&dpu_disp1_lcdif>;
+ };
+ };
+ };
+
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
+ backlight = <&backlight>;
+ data-mapping = "bgr666";
+ power-supply = <&reg_module_3v3>;
+ status = "disabled";
+ };
+
+ pcie_refclk: pcie-clock-generator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ pcie_refclk_gate: pcie-ref-clock {
+ compatible = "gpio-gate-clock";
+ #clock-cells = <0>;
+ clocks = <&pcie_refclk>;
+ enable-gpios = <&gpio_expander_43 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_module_3v3: regulator-module-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_module_3v3_avdd: regulator-module-3v3-avdd {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3_AVDD_AUDIO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_module_vref_1v8: regulator-module-vref-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vref-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+ * Shouldn't be used at A core and Linux side.
+ *
+ */
+ m4_reserved: m4@0x88000000 {
+ no-map;
+ reg = <0 0x88000000 0 0x8000000>;
+ };
+
+ rpmsg_reserved: rpmsg@0x90000000 {
+ no-map;
+ reg = <0 0x90200000 0 0x200000>;
+ };
+
+ decoder_boot: decoder-boot@84000000 {
+ reg = <0 0x84000000 0 0x2000000>;
+ no-map;
+ };
+
+ encoder_boot: encoder-boot@86000000 {
+ reg = <0 0x86000000 0 0x200000>;
+ no-map;
+ };
+
+ decoder_rpc: decoder-rpc@0x92000000 {
+ reg = <0 0x92000000 0 0x200000>;
+ no-map;
+ };
+
+ encoder_rpc: encoder-rpc@0x92200000 {
+ reg = <0 0x92200000 0 0x200000>;
+ no-map;
+ };
+
+ encoder_reserved: encoder_reserved@94400000 {
+ no-map;
+ reg = <0 0x94400000 0 0x800000>;
+ };
+
+ vdev0vring0: vdev0vring0@90000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@90008000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: vdev1vring0@90010000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: vdev1vring1@90018000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90018000 0 0x8000>;
+ no-map;
+ };
+
+ vdevbuffer: vdevbuffer {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90400000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8qxp-sgtl5000";
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&sgtl5000_a>;
+ clocks = <&mclkout0_lpcg 0>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai0>;
+ };
+ };
+
+ vdd_3v3_vga: regulator-vga-avcc {
+ compatible = "regulator-fixed";
+ regulator-name = "+3.3V_AVCC_VGA";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+/* Colibri Analogue Inputs */
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ status = "okay";
+ vref-supply = <&reg_module_vref_1v8>;
+};
+
+/* Colibri PWM_A */
+&adma_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_a>;
+ #pwm-cells = <3>;
+};
+
+&adma_lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ status = "disabled";
+};
+
+/* Display Prefetch Resolve, (Tiling) */
+&dc0_dpr1_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr1_channel3 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel1 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel2 {
+ status = "okay";
+};
+
+&dc0_dpr2_channel3 {
+ status = "okay";
+};
+
+&dc0_pc {
+ status = "okay";
+};
+
+&dc0_prg1 {
+ status = "okay";
+};
+
+&dc0_prg2 {
+ status = "okay";
+};
+
+&dc0_prg3 {
+ status = "okay";
+};
+
+&dc0_prg4 {
+ status = "okay";
+};
+
+&dc0_prg5 {
+ status = "okay";
+};
+
+&dc0_prg6 {
+ status = "okay";
+};
+
+&dc0_prg7 {
+ status = "okay";
+};
+
+&dc0_prg8 {
+ status = "okay";
+};
+
+&dc0_prg9 {
+ status = "okay";
+};
+
+&dpu1 {
+ status = "okay";
+};
+
+&dpu_disp1_lcdif {
+ remote-endpoint = <&lcd_display_in>;
+};
+
+&enet0_lpcg {
+ clocks = <&clk IMX_SC_R_ENET_0 IMX_SC_PM_CLK_PER>,
+ <&clk IMX_SC_R_ENET_0 IMX_SC_PM_CLK_PER>,
+ <&conn_axi_clk>,
+ <&clk IMX_SC_R_ENET_0 IMX_SC_C_DISABLE_50>,
+ <&conn_ipg_clk>,
+ <&conn_ipg_clk>;
+ clock-output-names = "enet0_lpcg_timer_clk",
+ "enet0_lpcg_txc_sampling_clk",
+ "enet0_lpcg_ahb_clk",
+ "enet0_lpcg_ref_50mhz_clk",
+ "enet0_lpcg_ipg_clk",
+ "enet0_lpcg_ipg_s_clk";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec1>;
+ pinctrl-1 = <&pinctrl_fec1_sleep>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ fsl,wakeup_irq = <0>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ max-speed = <100>;
+ reg = <2>;
+ };
+ };
+};
+
+/* Colibri optional CAN on UART_B RTS/CTS */
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_module_3v3>;
+};
+
+/* Colibri optional CAN on PS2 */
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_module_3v3>;
+};
+
+/* Colibri optional CAN on UART_A TXD/RXD */
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_module_3v3>;
+};
+
+&gpu_3d0 {
+ status = "okay";
+};
+
+&hsio_refb_clk {
+ status = "disabled";
+};
+
+/* On-module I2C */
+&i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ /*
+ * There is a shared clock between SGTL5000 and on-module USB hub,
+ * so it is a good way to handle pinmuxing for this clock on a parent
+ * device i2c0
+ */
+ pinctrl-0 = <&pinctrl_i2c0>, <&pinctrl_sgtl5000_usb_clk>;
+ status = "okay";
+
+ /* on-module Resistive Touch controller */
+ ad7879_ts: touchscreen@2c {
+ compatible = "adi,ad7879-1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ad7879_int>;
+ reg = <0x2c>;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ touchscreen-max-pressure = <4096>;
+ adi,resistance-plate-x = <120>;
+ adi,first-conversion-delay = /bits/ 8 <3>;
+ adi,acquisition-time = /bits/ 8 <1>;
+ adi,median-filter-size = /bits/ 8 <2>;
+ adi,averaging = /bits/ 8 <1>;
+ adi,conversion-interval = /bits/ 8 <255>;
+ status = "disabled";
+ };
+
+ /* GPIO expander */
+ gpio_expander_43: gpio-expander@43 {
+ compatible = "fcs,fxl6408";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x43>;
+ inital_io_dir = <0xff>;
+ inital_output = <0x05>;
+ gpio-line-names = "Wi-Fi_W_DISABLE", "Wi-Fi_WKUP_WLAN",
+ "PWR_EN_+V3.3_WiFi_N", "PCIe_REF_CLK_EN",
+ "USB_RESET_N", "USB_BYPASS_N", "Wi-Fi_PDn",
+ "Wi-Fi_WKUP_BT";
+ };
+
+ sgtl5000_a: codec@a {
+ compatible = "fsl,sgtl5000";
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg 0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12000000>, <12000000>;
+ clocks = <&mclkout0_lpcg 0>;
+ clock-names = "mclk";
+ reg = <0xa>;
+ VDDA-supply = <&reg_module_3v3_avdd>;
+ VDDD-supply = <&reg_module_vref_1v8>;
+ VDDIO-supply = <&reg_module_3v3>;
+ };
+
+ /* USB3503A */
+ usb3803@8 {
+ compatible = "smsc,usb3803";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3503a>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg 0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12000000>, <12000000>;
+ bypass-gpios = <&gpio_expander_43 5 GPIO_ACTIVE_LOW>;
+ clocks = <&mclkout0_lpcg 0>;
+ clock-names = "refclk";
+ disabled-ports = <2>;
+ initial-mode = <1>;
+ intn-gpios = <&lsio_gpio3 4 GPIO_ACTIVE_LOW>;
+ non-removable-devices = <1>;
+ reg = <0x8>;
+ reset-gpios = <&gpio_expander_43 4 GPIO_ACTIVE_LOW>;
+ };
+};
+
+/* MIPI DSI accessible on FFC (X2) */
+&i2c0_mipi_lvds0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* DSI to HDMI Adapter V1.1A */
+ pca9540_switch: i2c-switch@70 {
+ compatible = "nxp,pca9540";
+ reg = <0x70>;
+ i2c-mux-idle-disconnect;
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* DDC/EDID */
+ i2c_sw0: i2c-sw@0 {
+ reg = <0>;
+ };
+
+ /* DSI-HDMI converter */
+ i2c-sw@1 {
+ reg = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lt8912_hdmi: dsihdmi@48 {
+ compatible = "lontium,lt8912";
+ ddc-i2c-bus = <&i2c_sw0>;
+ hpd-gpios = <&lsio_gpio1 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_hpd>;
+ reg = <0x48>;
+
+ port {
+ lt8912_in: endpoint {
+ remote-endpoint = <&mipi0_dsi_host_out>;
+ };
+ };
+ };
+ };
+ };
+};
+
+/* On-module MIPI CSI I2C accessible on FFC (X3) */
+&i2c0_mipi_lvds1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
+};
+
+/* Colibri I2C */
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_conn>;
+ reg = <0x4a>;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 */
+ reset-gpios = <&lsio_gpio3 24 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */
+ status = "disabled";
+ };
+};
+
+&imx8_gpu_ss {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog0>, <&pinctrl_hog1>, <&pinctrl_hog2>,
+ <&pinctrl_ext_io0>, <&pinctrl_lpspi2_cs2>;
+
+ colibri-imx8qxp {
+ /* On-module touch pen-down interrupt */
+ pinctrl_ad7879_int: ad7879-int {
+ fsl,pins = <
+ IMX8QXP_MIPI_CSI0_I2C0_SCL_LSIO_GPIO3_IO05 0x21
+ >;
+ };
+
+ /* Colibri Analogue Inputs */
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <
+ IMX8QXP_ADC_IN0_ADMA_ADC_IN0 0x60 /* SODIMM 8 */
+ IMX8QXP_ADC_IN1_ADMA_ADC_IN1 0x60 /* SODIMM 6 */
+ IMX8QXP_ADC_IN4_ADMA_ADC_IN4 0x60 /* SODIMM 4 */
+ IMX8QXP_ADC_IN5_ADMA_ADC_IN5 0x60 /* SODIMM 2 */
+ >;
+ };
+
+ /* Atmel MXT touchsceen + boards with built-in Capacitive Touch Connector */
+ pinctrl_atmel_conn: mxt-ts-connector {
+ fsl,pins = <
+ IMX8QXP_QSPI0B_DATA2_LSIO_GPIO3_IO20 0x4000021 /* SODIMM 107 */
+ IMX8QXP_QSPI0B_SS1_B_LSIO_GPIO3_IO24 0x21 /* SODIMM 106 */
+ >;
+ };
+
+ /* Atmel MXT touchsceen + Capacitive Touch Adapter */
+ /* NOTE: This pingroup conflicts with pingroups
+ * pinctrl_pwm_b/pinctrl_pwm_c. Don't enable them
+ * simultaneously.
+ */
+ pinctrl_atmel_adap: mxt-ts-adapter {
+ fsl,pins = <
+ IMX8QXP_UART1_TX_LSIO_GPIO0_IO21 0x4000021 /* SODIMM 28 */
+ IMX8QXP_UART1_RX_LSIO_GPIO0_IO22 0x21 /* SODIMM 30 */
+ >;
+ };
+
+ pinctrl_can_int: can-int-grp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DQS_LSIO_GPIO3_IO13 0x40 /* SODIMM 73 */
+ >;
+ };
+
+ pinctrl_csi_ctl: csictlgrp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_SS0_B_LSIO_GPIO3_IO14 0x20 /* SODIMM 77 / X3-22 / CSI_CTL_GPIO2 */
+ IMX8QXP_QSPI0A_SS1_B_LSIO_GPIO3_IO15 0x20 /* SODIMM 89 / X3-11 / CSI_CTL_RESET# */
+ >;
+ };
+
+ pinctrl_csi_mclk: csimclkgrp {
+ fsl,pins = <
+ IMX8QXP_CSI_MCLK_CI_PI_MCLK 0xC0000041 /* SODIMM 75 / X3-12 */
+ >;
+ };
+
+ pinctrl_gpiokeys: gpiokeysgrp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DATA1_LSIO_GPIO3_IO10 0x06700041 /* SODIMM 45 */
+ >;
+ };
+
+ /* Colibri UART_B */
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <
+ IMX8QXP_UART0_RX_ADMA_UART0_RX 0x06000020 /* SODIMM 36 */
+ IMX8QXP_UART0_TX_ADMA_UART0_TX 0x06000020 /* SODIMM 38 */
+ IMX8QXP_FLEXCAN0_RX_ADMA_UART0_RTS_B 0x06000020 /* SODIMM 34 */
+ IMX8QXP_FLEXCAN0_TX_ADMA_UART0_CTS_B 0x06000020 /* SODIMM 32 */
+ >;
+ };
+
+ /* Colibri UART_C */
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ IMX8QXP_UART2_RX_ADMA_UART2_RX 0x06000020 /* SODIMM 19 */
+ IMX8QXP_UART2_TX_ADMA_UART2_TX 0x06000020 /* SODIMM 21 */
+ >;
+ };
+
+ /* Colibri UART_A */
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020 /* SODIMM 33 */
+ IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020 /* SODIMM 35 */
+ >;
+ };
+
+ /* Colibri UART_A Control */
+ pinctrl_lpuart3_ctrl: lpuart3ctrlgrp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00 0x20 /* SODIMM 23 */
+ IMX8QXP_SAI1_RXD_LSIO_GPIO0_IO29 0x20 /* SODIMM 25 */
+ IMX8QXP_SAI1_RXC_LSIO_GPIO0_IO30 0x20 /* SODIMM 27 */
+ IMX8QXP_CSI_RESET_LSIO_GPIO3_IO03 0x20 /* SODIMM 29 */
+ IMX8QXP_USDHC1_CD_B_LSIO_GPIO4_IO22 0x20 /* SODIMM 31 */
+ IMX8QXP_CSI_EN_LSIO_GPIO3_IO02 0x20 /* SODIMM 37 */
+ >;
+ };
+
+ /* Colibri Ethernet: On-module 100Mbps PHY Micrel KSZ8041 */
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0 /* Use pads in 3.3V mode */
+ IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0 /* Use pads in 3.3V mode */
+ IMX8QXP_ENET0_MDC_CONN_ENET0_MDC 0x06000020
+ IMX8QXP_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020
+ IMX8QXP_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x61
+ IMX8QXP_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_OUT 0x06000061
+ IMX8QXP_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x61
+ IMX8QXP_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x61
+ IMX8QXP_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x61
+ IMX8QXP_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x61
+ IMX8QXP_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x61
+ IMX8QXP_ENET0_RGMII_RXD2_CONN_ENET0_RMII_RX_ER 0x61
+ >;
+ };
+
+ pinctrl_fec1_sleep: fec1-sleep-grp {
+ fsl,pins = <
+ IMX8QXP_ENET0_MDC_LSIO_GPIO5_IO11 0x06000041
+ IMX8QXP_ENET0_MDIO_LSIO_GPIO5_IO10 0x06000041
+ IMX8QXP_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30 0x41
+ IMX8QXP_ENET0_RGMII_TXC_LSIO_GPIO4_IO29 0x41
+ IMX8QXP_ENET0_RGMII_TXD0_LSIO_GPIO4_IO31 0x41
+ IMX8QXP_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00 0x41
+ IMX8QXP_ENET0_RGMII_RX_CTL_LSIO_GPIO5_IO04 0x41
+ IMX8QXP_ENET0_RGMII_RXD0_LSIO_GPIO5_IO05 0x41
+ IMX8QXP_ENET0_RGMII_RXD1_LSIO_GPIO5_IO06 0x41
+ IMX8QXP_ENET0_RGMII_RXD2_LSIO_GPIO5_IO07 0x41
+ >;
+ };
+
+ /* Colibri LCD Back-Light GPIO */
+ pinctrl_gpio_bl_on: gpio-bl-on {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DATA3_LSIO_GPIO3_IO12 0x60 /* SODIMM 71 */
+ >;
+ };
+
+ /* HDMI Hot Plug Detect on FFC (X2) */
+ pinctrl_gpio_hpd: gpio-hpd {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO31 0x20 /* SODIMM 138 */
+ >;
+ };
+
+ pinctrl_hog0: hog0grp {
+ fsl,pins = <
+ IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0 /* Use pads in 3.3V mode */
+ >;
+ };
+
+ pinctrl_hog1: hog1grp {
+ fsl,pins = <
+ IMX8QXP_CSI_D07_CI_PI_D09 0x61 /* SODIMM 65 */
+ IMX8QXP_QSPI0A_DATA2_LSIO_GPIO3_IO11 0x20 /* SODIMM 69 */
+ IMX8QXP_SAI0_TXC_LSIO_GPIO0_IO26 0x20 /* SODIMM 79 */
+ IMX8QXP_CSI_D02_CI_PI_D04 0x61 /* SODIMM 79 */
+ IMX8QXP_ENET0_RGMII_RXC_LSIO_GPIO5_IO03 0x06000020 /* SODIMM 85 */
+ IMX8QXP_CSI_D06_CI_PI_D08 0x61 /* SODIMM 85 */
+ IMX8QXP_SAI0_RXD_LSIO_GPIO0_IO27 0x20 /* SODIMM 97 */
+ IMX8QXP_CSI_D03_CI_PI_D05 0x61 /* SODIMM 97 */
+ IMX8QXP_SAI0_TXFS_LSIO_GPIO0_IO28 0x20 /* SODIMM 101 */
+ IMX8QXP_CSI_D00_CI_PI_D02 0x61 /* SODIMM 101 */
+ IMX8QXP_SAI0_TXD_LSIO_GPIO0_IO25 0x20 /* SODIMM 103 */
+ IMX8QXP_CSI_D01_CI_PI_D03 0x61 /* SODIMM 103 */
+ IMX8QXP_QSPI0B_DATA1_LSIO_GPIO3_IO19 0x20 /* SODIMM 105 */
+ IMX8QXP_USB_SS3_TC2_LSIO_GPIO4_IO05 0x20 /* SODIMM 127 */
+ IMX8QXP_USB_SS3_TC3_LSIO_GPIO4_IO06 0x20 /* SODIMM 131 */
+ IMX8QXP_USB_SS3_TC1_LSIO_GPIO4_IO04 0x20 /* SODIMM 133 */
+ IMX8QXP_CSI_PCLK_LSIO_GPIO3_IO00 0x20 /* SODIMM 96 */
+ IMX8QXP_QSPI0B_DATA3_LSIO_GPIO3_IO21 0x20 /* SODIMM 98 */
+ IMX8QXP_SAI1_RXFS_LSIO_GPIO0_IO31 0x20 /* SODIMM 100 */
+ IMX8QXP_QSPI0B_DQS_LSIO_GPIO3_IO22 0x20 /* SODIMM 102 */
+ IMX8QXP_QSPI0B_SS0_B_LSIO_GPIO3_IO23 0x20 /* SODIMM 104 */
+ >;
+ };
+
+ pinctrl_hog2: hog2grp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_SCLK_LSIO_GPIO3_IO16 0x20 /* SODIMM 93 */
+ >;
+ };
+
+ pinctrl_hog3: hog3grp {
+ fsl,pins = <
+ IMX8QXP_CSI_MCLK_LSIO_GPIO3_IO01 0x20 /* SODIMM 75 */
+ >;
+ };
+
+ /*
+ * This pin is used in the SCFW as a UART. Using it from
+ * Linux would require rewritting the SCFW board file.
+ */
+ pinctrl_hog_scfw: hogscfwgrp {
+ fsl,pins = <
+ IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03 0x20 /* SODIMM 144 */
+ >;
+ };
+
+ /* On Module I2C */
+ pinctrl_i2c0: i2c0grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_CSI0_GPIO0_00_ADMA_I2C0_SCL 0x06000021
+ IMX8QXP_MIPI_CSI0_GPIO0_01_ADMA_I2C0_SDA 0x06000021
+ >;
+ };
+
+ /* Colibri I2C */
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI0_GPIO0_00_ADMA_I2C1_SCL 0x06000021 /* SODIMM 196 */
+ IMX8QXP_MIPI_DSI0_GPIO0_01_ADMA_I2C1_SDA 0x06000021 /* SODIMM 194 */
+ >;
+ };
+
+ /* Colibri optional CAN on UART_B RTS/CTS */
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN0_TX_ADMA_FLEXCAN0_TX 0x21 /* SODIMM 32 */
+ IMX8QXP_FLEXCAN0_RX_ADMA_FLEXCAN0_RX 0x21 /* SODIMM 34 */
+ >;
+ };
+
+ /* Colibri optional CAN on PS2 */
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN1_TX_ADMA_FLEXCAN1_TX 0x21 /* SODIMM 55 */
+ IMX8QXP_FLEXCAN1_RX_ADMA_FLEXCAN1_RX 0x21 /* SODIMM 63 */
+ >;
+ };
+
+ /* Colibri optional CAN on UART_A TXD/RXD */
+ pinctrl_flexcan3: flexcan2grp {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN2_TX_ADMA_FLEXCAN2_TX 0x21 /* SODIMM 35 */
+ IMX8QXP_FLEXCAN2_RX_ADMA_FLEXCAN2_RX 0x21 /* SODIMM 33 */
+ >;
+ };
+
+ /* On module wifi module */
+ pinctrl_pcieb: pciebgrp {
+ fsl,pins = <
+ IMX8QXP_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01 0x04000061 /* SODIMM 178 */
+ IMX8QXP_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02 0x04000061 /* SODIMM 94 */
+ IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00 0x60 /* SODIMM 81 */
+ >;
+ };
+
+ /* Colibri PWM_A */
+ pinctrl_pwm_a: pwma {
+ /* both pins are connected together, reserve the unused CSI_D05 */
+ fsl,pins = <
+ IMX8QXP_CSI_D05_CI_PI_D07 0x61 /* SODIMM 59 */
+ IMX8QXP_SPI0_CS1_ADMA_LCD_PWM0_OUT 0x60 /* SODIMM 59 */
+ >;
+ };
+
+ /* Colibri PWM_B */
+ pinctrl_pwm_b: pwmb {
+ fsl,pins = <
+ IMX8QXP_UART1_TX_LSIO_PWM0_OUT 0x60 /* SODIMM 28 */
+ >;
+ };
+
+ /* Colibri PWM_C */
+ pinctrl_pwm_c: pwmc {
+ fsl,pins = <
+ IMX8QXP_UART1_RX_LSIO_PWM1_OUT 0x60 /* SODIMM 30 */
+ >;
+ };
+
+ /* Colibri PWM_D */
+ pinctrl_pwm_d: pwmd {
+ /* both pins are connected together, reserve the unused CSI_D04 */
+ fsl,pins = <
+ IMX8QXP_CSI_D04_CI_PI_D06 0x61 /* SODIMM 67 */
+ IMX8QXP_UART1_RTS_B_LSIO_PWM2_OUT 0x60 /* SODIMM 67 */
+ >;
+ };
+
+ /* On-module I2S */
+ pinctrl_sai0: sai0grp {
+ fsl,pins = <
+ IMX8QXP_SPI0_SDI_ADMA_SAI0_TXD 0x06000040
+ IMX8QXP_SPI0_CS0_ADMA_SAI0_RXD 0x06000040
+ IMX8QXP_SPI0_SCK_ADMA_SAI0_TXC 0x06000040
+ IMX8QXP_SPI0_SDO_ADMA_SAI0_TXFS 0x06000040
+ >;
+ };
+
+ /* Colibri Audio Analogue Microphone GND */
+ pinctrl_sgtl5000: sgtl5000 {
+ fsl,pins = <
+ /* MIC GND EN */
+ IMX8QXP_MIPI_CSI0_I2C0_SDA_LSIO_GPIO3_IO06 0x41
+ >;
+ };
+
+ /* On-module SGTL5000 clock */
+ pinctrl_sgtl5000_usb_clk: sgtl5000-usb-clk {
+ fsl,pins = <
+ IMX8QXP_ADC_IN3_ADMA_ACM_MCLK_OUT0 0x21
+ >;
+ };
+
+ /* On-module USB interrupt */
+ pinctrl_usb3503a: usb3503a-grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_CSI0_MCLK_OUT_LSIO_GPIO3_IO04 0x61
+ >;
+ };
+
+ /* Colibri USB Client Cable Detect */
+ pinctrl_usbc_det: usbc-det {
+ fsl,pins = <
+ IMX8QXP_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x06000040 /* SODIMM 137 */
+ >;
+ };
+
+ pinctrl_ext_io0: ext-io0 {
+ fsl,pins = <
+ IMX8QXP_ENET0_RGMII_RXD3_LSIO_GPIO5_IO08 0x06000040 /* SODIMM 135 */
+ >;
+ };
+
+ /* Colibri Parallel RGB LCD Interface */
+ pinctrl_lcdif: lcdif-pins {
+ fsl,pins = <
+ IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19 0x40 /* SODIMM 44 */
+ IMX8QXP_MCLK_IN1_ADMA_LCDIF_EN 0x40 /* SODIMM 44 */
+ IMX8QXP_MCLK_OUT0_ADMA_LCDIF_CLK 0x60 /* SODIMM 56 */
+ IMX8QXP_SPI3_CS0_ADMA_LCDIF_HSYNC 0x60 /* SODIMM 68 */
+ IMX8QXP_MCLK_IN0_ADMA_LCDIF_VSYNC 0x60 /* SODIMM 82 */
+ IMX8QXP_ESAI0_FSR_ADMA_LCDIF_D00 0x60 /* SODIMM 76 */
+ IMX8QXP_USDHC1_WP_LSIO_GPIO4_IO21 0x60 /* SODIMM 76 */
+ IMX8QXP_ESAI0_FST_ADMA_LCDIF_D01 0x60 /* SODIMM 70 */
+ IMX8QXP_ESAI0_SCKR_ADMA_LCDIF_D02 0x60 /* SODIMM 60 */
+ IMX8QXP_ESAI0_SCKT_ADMA_LCDIF_D03 0x60 /* SODIMM 58 */
+ IMX8QXP_ESAI0_TX0_ADMA_LCDIF_D04 0x60 /* SODIMM 78 */
+ IMX8QXP_ESAI0_TX1_ADMA_LCDIF_D05 0x60 /* SODIMM 72 */
+ IMX8QXP_ESAI0_TX2_RX3_ADMA_LCDIF_D06 0x60 /* SODIMM 80 */
+ IMX8QXP_ESAI0_TX3_RX2_ADMA_LCDIF_D07 0x60 /* SODIMM 46 */
+ IMX8QXP_ESAI0_TX4_RX1_ADMA_LCDIF_D08 0x60 /* SODIMM 62 */
+ IMX8QXP_ESAI0_TX5_RX0_ADMA_LCDIF_D09 0x60 /* SODIMM 48 */
+ IMX8QXP_SPDIF0_RX_ADMA_LCDIF_D10 0x60 /* SODIMM 74 */
+ IMX8QXP_SPDIF0_TX_ADMA_LCDIF_D11 0x60 /* SODIMM 50 */
+ IMX8QXP_SPDIF0_EXT_CLK_ADMA_LCDIF_D12 0x60 /* SODIMM 52 */
+ IMX8QXP_SPI3_SCK_ADMA_LCDIF_D13 0x60 /* SODIMM 54 */
+ IMX8QXP_SPI3_SDO_ADMA_LCDIF_D14 0x60 /* SODIMM 66 */
+ IMX8QXP_SPI3_SDI_ADMA_LCDIF_D15 0x60 /* SODIMM 64 */
+ IMX8QXP_SPI3_CS1_ADMA_LCDIF_D16 0x60 /* SODIMM 57 */
+ IMX8QXP_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01 0x60 /* SODIMM 57 */
+ IMX8QXP_UART1_CTS_B_ADMA_LCDIF_D17 0x60 /* SODIMM 61 */
+ >;
+ };
+
+ /* LVDS converter on Iris v2.0 */
+ pinctrl_lvds_converter: lcd-lvds {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN1_TX_LSIO_GPIO1_IO18 0x20 /* SODIMM 55 */
+ /* 6B/8B mode. Select LOW - 8B mode (24bit) */
+ IMX8QXP_FLEXCAN1_RX_LSIO_GPIO1_IO17 0x20 /* SODIMM 63 */
+ IMX8QXP_QSPI0B_SCLK_LSIO_GPIO3_IO17 0x20 /* SODIMM 95 */
+ IMX8QXP_QSPI0B_DATA0_LSIO_GPIO3_IO18 0x20 /* SODIMM 99 */
+ >;
+ };
+
+ /* USB Host Power Enable */
+ pinctrl_usbh1_reg: usbh1-reg {
+ fsl,pins = <
+ IMX8QXP_USB_SS3_TC0_LSIO_GPIO4_IO03 0x06000040 /* SODIMM 129 */
+ >;
+ };
+
+ /* On-module eMMC */
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x21
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x21
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x21
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x21
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x21
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x21
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x21
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x21
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x21
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x41
+ IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x21
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x21
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x21
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x21
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x21
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x21
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x21
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x21
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x21
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x21
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x41
+ IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x21
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x21
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x21
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x21
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x21
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x21
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x21
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x21
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x21
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x21
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x41
+ IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x21
+ >;
+ };
+
+ /* Colibri SDCard CardDetect */
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DATA0_LSIO_GPIO3_IO09 0x06000021 /* SODIMM 43 */
+ >;
+ };
+
+ pinctrl_usdhc2_gpio_sleep: usdhc2gpioslpgrp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DATA0_LSIO_GPIO3_IO09 0x60 /* SODIMM 43 */
+ >;
+ };
+
+ /* Colibri SDCard */
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 /* SODIMM 47 */
+ IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x21 /* SODIMM 190 */
+ IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x21 /* SODIMM 192 */
+ IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x21 /* SODIMM 49 */
+ IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x21 /* SODIMM 51 */
+ IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x21 /* SODIMM 53 */
+ IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x21
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 /* SODIMM 47 */
+ IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x21 /* SODIMM 190 */
+ IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x21 /* SODIMM 192 */
+ IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x21 /* SODIMM 49 */
+ IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x21 /* SODIMM 51 */
+ IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x21 /* SODIMM 53 */
+ IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x21
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 /* SODIMM 47 */
+ IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x21 /* SODIMM 190 */
+ IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x21 /* SODIMM 192 */
+ IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x21 /* SODIMM 49 */
+ IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x21 /* SODIMM 51 */
+ IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x21 /* SODIMM 53 */
+ IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x21
+ >;
+ };
+
+ pinctrl_usdhc2_sleep: usdhc2slpgrp {
+ fsl,pins = <
+ IMX8QXP_USDHC1_CLK_LSIO_GPIO4_IO23 0x60 /* SODIMM 47 */
+ IMX8QXP_USDHC1_CMD_LSIO_GPIO4_IO24 0x60 /* SODIMM 190 */
+ IMX8QXP_USDHC1_DATA0_LSIO_GPIO4_IO25 0x60 /* SODIMM 192 */
+ IMX8QXP_USDHC1_DATA1_LSIO_GPIO4_IO26 0x60 /* SODIMM 49 */
+ IMX8QXP_USDHC1_DATA2_LSIO_GPIO4_IO27 0x60 /* SODIMM 51 */
+ IMX8QXP_USDHC1_DATA3_LSIO_GPIO4_IO28 0x60 /* SODIMM 53 */
+ IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x21
+ >;
+ };
+
+ /* MIPI DSI I2C accessible on SODIMM (X1) and FFC (X2) */
+ pinctrl_i2c0_mipi_lvds0: mipi_lvds0_i2c0_grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020 /* SODIMM 140 */
+ IMX8QXP_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020 /* SODIMM 142 */
+ >;
+ };
+
+ /* MIPI CSI I2C accessible on SODIMM (X1) and FFC (X3) */
+ pinctrl_i2c0_mipi_lvds1: mipi_lvds1_i2c0_grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc6000020 /* SODIMM 186 */
+ IMX8QXP_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc6000020 /* SODIMM 188 */
+ >;
+ };
+
+ /* Colibri SPI */
+ pinctrl_lpspi2: lpspi2 {
+ fsl,pins = <
+ IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00 0x21 /* SODIMM 86 */
+ IMX8QXP_SPI2_SDO_ADMA_SPI2_SDO 0x06000040 /* SODIMM 92 */
+ IMX8QXP_SPI2_SDI_ADMA_SPI2_SDI 0x06000040 /* SODIMM 90 */
+ IMX8QXP_SPI2_SCK_ADMA_SPI2_SCK 0x06000040 /* SODIMM 88 */
+ >;
+ };
+
+ pinctrl_lpspi2_cs2: lpspi2-cs2 {
+ fsl,pins = <
+ IMX8QXP_ENET0_RGMII_TXD3_LSIO_GPIO5_IO02 0x21 /* SODIMM 65 */
+ >;
+ };
+
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ IMX8QXP_SCU_BOOT_MODE3_SCU_DSC_RTC_CLOCK_OUTPUT_32K 0x20
+ >;
+ };
+ };
+};
+
+&irqsteer_csi0 {
+ status = "okay";
+};
+
+&isi_0 {
+ /**
+ * interface = <Input MIPI_VCx Output>
+ * Input: 0-DC0, 1-DC1, 2-MIPI CSI0, 3-MIPI CSI1, 4-HDMI, 5-MEM, INPUT: 6-PARALLEL CSI
+ * MIPI_VCx: 0-VC0, 1-VC1, 2-VC2, 3-VC3, MIPI CSI only
+ * Output: 0-DC0, 1-DC1, 2-MEM
+ */
+ interface = <2 0 2>;
+
+ cap_device {
+ status = "okay";
+ };
+
+ m2m_device {
+ status = "okay";
+ };
+};
+
+&isi_1 {
+ interface = <6 0 2>;
+ parallel_csi;
+};
+
+/* Colibri SPI */
+&lpspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi2>;
+ cs-gpios = <&lsio_gpio1 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
+/* Colibri UART_B */
+&lpuart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+};
+
+/* Colibri UART_C */
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+};
+
+/* Colibri UART_A */
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>, <&pinctrl_lpuart3_ctrl>;
+};
+
+&lsio_gpio0 {
+ gpio-line-names = "",
+ "SODIMM_70",
+ "SODIMM_60",
+ "SODIMM_58",
+ "SODIMM_78",
+ "SODIMM_72",
+ "SODIMM_80",
+ "SODIMM_46",
+ "SODIMM_62",
+ "SODIMM_48",
+ "SODIMM_74",
+ "SODIMM_50",
+ "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_66",
+ "SODIMM_64",
+ "SODIMM_68",
+ "",
+ "",
+ "SODIMM_82",
+ "SODIMM_56",
+ "SODIMM_28",
+ "SODIMM_30",
+ "",
+ "SODIMM_61",
+ "SODIMM_103",
+ "",
+ "",
+ "",
+ "SODIMM_25",
+ "SODIMM_27",
+ "SODIMM_100";
+ status = "okay";
+};
+
+&lsio_gpio1 {
+ gpio-line-names = "SODIMM_86",
+ "SODIMM_92",
+ "SODIMM_90",
+ "SODIMM_88",
+ "",
+ "",
+ "",
+ "SODIMM_59",
+ "",
+ "SODIMM_6",
+ "SODIMM_8",
+ "",
+ "",
+ "SODIMM_2",
+ "SODIMM_4",
+ "SODIMM_34",
+ "SODIMM_32",
+ "SODIMM_63",
+ "SODIMM_55",
+ "SODIMM_33",
+ "SODIMM_35",
+ "SODIMM_36",
+ "SODIMM_38",
+ "SODIMM_21",
+ "SODIMM_19",
+ "SODIMM_140",
+ "SODIMM_142",
+ "SODIMM_196",
+ "SODIMM_194",
+ "SODIMM_186",
+ "SODIMM_188",
+ "SODIMM_138";
+ status = "okay";
+};
+
+&lsio_gpio2 {
+ gpio-line-names = "SODIMM_23",
+ "",
+ "",
+ "SODIMM_144";
+ status = "okay";
+};
+
+&lsio_gpio3 {
+ gpio-line-names = "SODIMM_96",
+ "SODIMM_75",
+ "SODIMM_37",
+ "SODIMM_29",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_43",
+ "SODIMM_45",
+ "SODIMM_69",
+ "SODIMM_71",
+ "SODIMM_73",
+ "SODIMM_77",
+ "SODIMM_89",
+ "SODIMM_93",
+ "SODIMM_95",
+ "SODIMM_99",
+ "SODIMM_105",
+ "SODIMM_107",
+ "SODIMM_98",
+ "SODIMM_102",
+ "SODIMM_104",
+ "SODIMM_106";
+ status = "okay";
+};
+
+&lsio_gpio4 {
+ gpio-line-names = "",
+ "",
+ "",
+ "SODIMM_129",
+ "SODIMM_133",
+ "SODIMM_127",
+ "SODIMM_131",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_44",
+ "",
+ "SODIMM_76",
+ "SODIMM_31",
+ "SODIMM_47",
+ "SODIMM_190",
+ "SODIMM_192",
+ "SODIMM_49",
+ "SODIMM_51",
+ "SODIMM_53";
+ status = "okay";
+};
+
+&lsio_gpio5 {
+ gpio-line-names = "",
+ "SODIMM_57",
+ "SODIMM_65",
+ "SODIMM_85",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_135",
+ "SODIMM_137",
+ "UNUSABLE_SODIMM_180",
+ "UNUSABLE_SODIMM_184";
+ status = "okay";
+};
+
+/* MIPI CSI accessible via FFC (X3) */
+&mipi_csi_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /delete-property/virtual-channel;
+};
+
+&mipi0_dsi_host {
+ pwr-delay = <10>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@1 {
+ reg = <1>;
+ mipi0_dsi_host_out: endpoint {
+ remote-endpoint = <&lt8912_in>;
+ };
+ };
+ };
+};
+
+&mipi1_dsi_host {
+ pwr-delay = <10>;
+};
+
+/* On-module PCIe for Wi-Fi */
+&pcieb{
+ compatible = "fsl,imx8qxp-pcie","snps,dw-pcie";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb &pinctrl_wifi>;
+ clocks = <&pcieb_lpcg 0>,
+ <&pcieb_lpcg 1>,
+ <&pcieb_lpcg 2>,
+ <&phyx1_lpcg 0>,
+ <&phyx1_crr1_lpcg 0>,
+ <&pcieb_crr3_lpcg 0>,
+ <&misc_crr5_lpcg 0>,
+ <&pcie_refclk_gate>;
+ clock-names = "pcie", "pcie_bus", "pcie_inbound_axi",
+ "pcie_phy", "phy_per", "pcie_per", "misc_per",
+ "pcie_ext";
+
+ clkreq-gpio = <&lsio_gpio4 1 GPIO_ACTIVE_LOW>;
+ ext_osc = <1>;
+ fsl,max-link-speed = <1>;
+ hard-wired = <1>;
+ disable-gpio = <&gpio_expander_43 6 GPIO_ACTIVE_LOW>;
+ power-on-gpio = <&gpio_expander_43 2 GPIO_ACTIVE_LOW>;
+ reserved-region = <&rpmsg_reserved>;
+ reset-gpio = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+/* Colibri PWM_B */
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_b>;
+ #pwm-cells = <3>;
+};
+
+/* Colibri PWM_C */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_c>;
+ #pwm-cells = <3>;
+};
+
+/* Colibri PWM_D */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_d>;
+ #pwm-cells = <3>;
+};
+
+&rpmsg{
+ /*
+ * 64K for one rpmsg instance:
+ */
+ vdev-nums = <2>;
+ reg = <0x0 0x90000000 0x0 0x20000>;
+ memory-region = <&vdevbuffer>;
+ status = "okay";
+};
+
+/* On-module I2S */
+&sai0 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ status = "okay";
+};
+
+&thermal_zones {
+ cpu-thermal0 {
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit0: trip1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pmic-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens IMX_SC_R_PMIC_0>;
+
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ pmic_cooling_map0: map0 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
+
+/* On-module eMMC */
+&usdhc1 {
+ bus-width = <8>;
+ no-sd;
+ no-sdio;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ status = "okay";
+};
+
+/* Colibri SDCard */
+&usdhc2 {
+ bus-width = <4>;
+ cd-gpios = <&lsio_gpio3 9 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ no-1-8-v;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
+ vmmc-supply = <&reg_module_3v3>;
+};
+
+&vpu_decoder {
+ boot-region = <&decoder_boot>;
+ rpc-region = <&decoder_rpc>;
+ reg-csr = <0x2d040000>;
+ core_type = <1>;
+ status = "okay";
+};
+
+&vpu_encoder {
+ boot-region = <&encoder_boot>;
+ rpc-region = <&encoder_rpc>;
+ reserved-region = <&encoder_reserved>;
+ reg-rpc-system = <0x40000000>;
+ resolution-max = <1920 1920>;
+ mbox-names = "enc1_tx0", "enc1_tx1", "enc1_rx";
+ mboxes = <&mu1_m0 0 0
+ &mu1_m0 0 1
+ &mu1_m0 1 0>;
+ status = "okay";
+
+ core0@1020000 {
+ compatible = "fsl,imx8-mu1-vpu-m0";
+ reg = <0x1020000 0x20000>;
+ reg-csr = <0x1050000 0x10000>;
+ interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,vpu_ap_mu_id = <17>;
+ fw-buf-size = <0x200000>;
+ rpc-buf-size = <0x80000>;
+ print-buf-size = <0x80000>;
+ };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4feedf07cfb5..b8cab25eff50 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -23,46 +23,16 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
-CONFIG_ARCH_AGILEX=y
-CONFIG_ARCH_SUNXI=y
-CONFIG_ARCH_ALPINE=y
-CONFIG_ARCH_BCM2835=y
-CONFIG_ARCH_BCM_IPROC=y
-CONFIG_ARCH_BERLIN=y
-CONFIG_ARCH_BRCMSTB=y
-CONFIG_ARCH_EXYNOS=y
-CONFIG_ARCH_K3=y
-CONFIG_ARCH_LAYERSCAPE=y
-CONFIG_ARCH_LG1K=y
-CONFIG_ARCH_HISI=y
-CONFIG_ARCH_MEDIATEK=y
-CONFIG_ARCH_MESON=y
-CONFIG_ARCH_MVEBU=y
CONFIG_ARCH_MXC=y
-CONFIG_ARCH_QCOM=y
-CONFIG_ARCH_RENESAS=y
-CONFIG_ARCH_ROCKCHIP=y
-CONFIG_ARCH_S32=y
-CONFIG_SOC_S32V234=y
-CONFIG_ARCH_SEATTLE=y
-CONFIG_ARCH_STRATIX10=y
-CONFIG_ARCH_SYNQUACER=y
-CONFIG_ARCH_TEGRA=y
-CONFIG_ARCH_SPRD=y
-CONFIG_ARCH_THUNDER=y
-CONFIG_ARCH_THUNDER2=y
-CONFIG_ARCH_UNIPHIER=y
-CONFIG_ARCH_VEXPRESS=y
-CONFIG_ARCH_XGENE=y
-CONFIG_ARCH_ZX=y
-CONFIG_ARCH_ZYNQMP=y
CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_NUMA=y
@@ -70,7 +40,7 @@ CONFIG_SECCOMP=y
CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
CONFIG_XEN=y
-CONFIG_COMPAT=y
+CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_RANDOMIZE_BASE=y
CONFIG_PM_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y
@@ -80,25 +50,20 @@ CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_ACPI_CPPC_CPUFREQ=m
-CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
CONFIG_ARM_SCPI_CPUFREQ=y
CONFIG_ARM_IMX_CPUFREQ_DT=y
-CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
-CONFIG_ARM_TEGRA186_CPUFREQ=y
-CONFIG_QORIQ_CPUFREQ=y
CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_INTEL_STRATIX10_SERVICE=y
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_IMX_DSP=y
CONFIG_IMX_SCU=y
CONFIG_IMX_SCU_PD=y
+CONFIG_IMX_SECO_MU=y
CONFIG_ACPI=y
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
@@ -113,19 +78,24 @@ CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_SHA512_ARM64_CE=m
CONFIG_CRYPTO_SHA3_ARM64=m
CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_CRYPTO_SM4_ARM64_CE=m
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_NHPOLY1305_NEON=m
CONFIG_CRYPTO_AES_ARM64_BS=m
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_KSM=y
CONFIG_MEMORY_FAILURE=y
CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_ZSMALLOC=y
+CONFIG_PGTABLE_MAPPING=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -155,19 +125,28 @@ CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_BRIDGE=m
-CONFIG_BRIDGE_VLAN_FILTERING=y
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_VLAN_8021Q=m
CONFIG_LLC2=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_CBS=y
+CONFIG_NET_SCH_TAPRIO=y
+CONFIG_NET_SCH_MQPRIO=y
+CONFIG_NET_CLS_BASIC=y
+CONFIG_NET_CLS_TCINDEX=y
CONFIG_TSN=y
CONFIG_NET_SWITCHDEV=y
-CONFIG_QRTR=m
-CONFIG_QRTR_SMD=m
-CONFIG_QRTR_TUN=m
CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=y
CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_VXCAN=m
+CONFIG_CAN_SLCAN=m
CONFIG_CAN_FLEXCAN=m
-CONFIG_BT=y
+CONFIG_CAN_MCP251X=m
+CONFIG_CAN_MCP25XXFD=m
+CONFIG_BT=m
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
@@ -179,53 +158,42 @@ CONFIG_BT_HIDP=y
CONFIG_BT_LEDS=y
# CONFIG_BT_DEBUGFS is not set
CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_HCIUART_QCA=y
-CONFIG_BT_HCIVHCI=y
-CONFIG_CFG80211=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_WILINK=m
+CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_CFG80211_WEXT=y
-CONFIG_MAC80211=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
-CONFIG_NET_9P=y
-CONFIG_NET_9P_VIRTIO=y
+CONFIG_RFKILL=m
+CONFIG_RFKILL_GPIO=m
+CONFIG_NET_9P=m
+CONFIG_NET_9P_VIRTIO=m
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCI_IOV=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
-CONFIG_PCI_AARDVARK=y
-CONFIG_PCI_TEGRA=y
-CONFIG_PCIE_RCAR=y
CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCI_XGENE=y
-CONFIG_PCIE_ALTERA=y
-CONFIG_PCIE_ALTERA_MSI=y
-CONFIG_PCI_HOST_THUNDER_PEM=y
-CONFIG_PCI_HOST_THUNDER_ECAM=y
-CONFIG_PCIE_ROCKCHIP_HOST=m
-CONFIG_PCI_IMX6=y
-CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCI_HISI=y
-CONFIG_PCIE_QCOM=y
-CONFIG_PCIE_ARMADA_8K=y
-CONFIG_PCIE_KIRIN=y
-CONFIG_PCIE_HISI_STB=y
-CONFIG_PCIE_TEGRA194=m
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
+CONFIG_PCI_IMX6_HOST=y
+CONFIG_PCI_IMX6_EP=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_FW_LOADER_USER_HELPER=y
-CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
-CONFIG_HISILICON_LPC=y
+CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_SIMPLE_PM_BUS=y
-CONFIG_FSL_MC_BUS=y
-CONFIG_FSL_MC_UAPI_SUPPORT=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
@@ -240,22 +208,23 @@ CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_NAND_DENALI_DT=y
-CONFIG_MTD_NAND_MARVELL=y
-CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_NAND_GPMI_NAND=y
-CONFIG_MTD_NAND_QCOM=y
CONFIG_MTD_SPI_NOR=y
# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
CONFIG_MTD_UBI=y
+CONFIG_ZRAM=y
+CONFIG_ZRAM_WRITEBACK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
+CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_NVME=y
-CONFIG_SENSORS_FXOS8700=y
-CONFIG_SENSORS_FXAS2100X=y
+CONFIG_SENSORS_FXOS8700=m
+CONFIG_SENSORS_FXAS2100X=m
CONFIG_SRAM=y
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_AT25=m
+CONFIG_TI_ST=m
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_SAS_ATA=y
@@ -264,18 +233,12 @@ CONFIG_SCSI_HISI_SAS_PCI=y
CONFIG_SCSI_MPT3SAS=m
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
-CONFIG_SCSI_UFS_QCOM=m
-CONFIG_SCSI_UFS_HISI=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_IMX=y
CONFIG_AHCI_CEVA=y
-CONFIG_AHCI_MVEBU=y
-CONFIG_AHCI_XGENE=y
-CONFIG_AHCI_QORIQ=y
CONFIG_SATA_SIL24=y
-CONFIG_SATA_RCAR=y
CONFIG_PATA_PLATFORM=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_MD=y
@@ -289,216 +252,165 @@ CONFIG_MACVTAP=m
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
-CONFIG_AMD_XGBE=y
-CONFIG_NET_XGENE=y
-CONFIG_ATL1C=m
-CONFIG_BNX2X=m
-CONFIG_MACB=y
-CONFIG_THUNDER_NIC_PF=y
CONFIG_FEC=y
-CONFIG_FSL_SDK_DPAA_ETH=y
-CONFIG_FSL_DPAA2_ETH=y
-CONFIG_FSL_ENETC=y
-CONFIG_FSL_ENETC_VF=y
-CONFIG_FSL_ENETC_MDIO=y
-CONFIG_ENETC_TSN=y
-CONFIG_HIX5HD2_GMAC=y
-CONFIG_HNS_DSAF=y
-CONFIG_HNS_ENET=y
-CONFIG_HNS3=y
-CONFIG_HNS3_HCLGE=y
-CONFIG_HNS3_ENET=y
-CONFIG_E1000=y
-CONFIG_E1000E=y
-CONFIG_IGB=y
-CONFIG_IGBVF=y
-CONFIG_MVNETA=y
-CONFIG_MVPP2=y
-CONFIG_SKY2=y
+CONFIG_E1000=m
+CONFIG_E1000E=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
+CONFIG_SKY2=m
CONFIG_MLX4_EN=m
CONFIG_MLX5_CORE=m
CONFIG_MLX5_CORE_EN=y
-CONFIG_MSCC_OCELOT_SWITCH=y
-CONFIG_QCOM_EMAC=m
-CONFIG_RAVB=y
-CONFIG_SMC91X=y
-CONFIG_SMSC911X=y
-CONFIG_SNI_AVE=y
-CONFIG_SNI_NETSEC=y
-CONFIG_STMMAC_ETH=m
+CONFIG_SMC91X=m
+CONFIG_SMSC911X=m
+CONFIG_STMMAC_ETH=y
+CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
-CONFIG_AQUANTIA_PHY=y
-CONFIG_AT803X_PHY=y
-CONFIG_INPHI_PHY=y
+CONFIG_AT803X_PHY=m
+CONFIG_INPHI_PHY=m
CONFIG_MARVELL_PHY=m
-CONFIG_MARVELL_10G_PHY=m
-CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_NXP_TJA11XX_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_ROCKCHIP_PHY=y
-CONFIG_VITESSE_PHY=y
+CONFIG_MICROSEMI_PHY=m
+CONFIG_NXP_TJA11XX_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_ASYNC=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
-CONFIG_USB_USBNET=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SR9800=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
-CONFIG_BRCMFMAC=m
-CONFIG_BRCMFMAC_PCIE=y
-CONFIG_HOSTAP=y
-CONFIG_WL18XX=m
-CONFIG_WLCORE_SDIO=m
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_PCIE=m
+CONFIG_MWIFIEX_USB=m
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_NXP is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_RTL_CARDS is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_IVSHMEM_NET=m
+CONFIG_INPUT_MATRIXKMAP=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SNVS_PWRKEY=y
CONFIG_KEYBOARD_IMX_SC_PWRKEY=y
-CONFIG_KEYBOARD_CROS_EC=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_COLIBRI_VF50=m
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C=m
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_PM8941_PWRKEY=y
-CONFIG_INPUT_HISI_POWERKEY=y
-CONFIG_INPUT_MPL3115=y
-CONFIG_INPUT_ISL29023=y
+CONFIG_INPUT_MPL3115=m
+CONFIG_INPUT_ISL29023=m
# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIO_AMBAKMI=m
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_BCM2835AUX=y
CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_OMAP=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_UNIPHIER=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_MESON=y
-CONFIG_SERIAL_MESON_CONSOLE=y
-CONFIG_SERIAL_SAMSUNG=y
-CONFIG_SERIAL_SAMSUNG_CONSOLE=y
-CONFIG_SERIAL_TEGRA=y
-CONFIG_SERIAL_TEGRA_TCU=y
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_MSM=y
-CONFIG_SERIAL_MSM_CONSOLE=y
-CONFIG_SERIAL_QCOM_GENI=y
-CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
-CONFIG_SERIAL_XILINX_PS_UART=y
-CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SERIAL_FSL_LPUART=y
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_FSL_LINFLEXUART=y
CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
-CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_IPMI_HANDLER=m
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_TCG_TPM=y
-CONFIG_TCG_TIS_I2C_INFINEON=y
+CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
-CONFIG_I2C_BCM2835=m
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_GPIO=m
CONFIG_I2C_IMX=y
CONFIG_I2C_IMX_LPI2C=y
-CONFIG_I2C_MESON=y
-CONFIG_I2C_MV64XXX=y
-CONFIG_I2C_PXA=y
-CONFIG_I2C_QCOM_GENI=m
-CONFIG_I2C_QUP=y
CONFIG_I2C_RK3X=y
CONFIG_I2C_RPBUS=y
-CONFIG_I2C_SH_MOBILE=y
-CONFIG_I2C_TEGRA=y
-CONFIG_I2C_UNIPHIER_F=y
-CONFIG_I2C_RCAR=y
-CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_XEN_I2C_BACKEND=y
+CONFIG_I2C_SLAVE=y
CONFIG_SPI=y
-CONFIG_SPI_ARMADA_3700=y
-CONFIG_SPI_BCM2835=m
-CONFIG_SPI_BCM2835AUX=m
CONFIG_SPI_FSL_LPSPI=y
CONFIG_SPI_FSL_QUADSPI=y
CONFIG_SPI_NXP_FLEXSPI=y
+CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
-CONFIG_SPI_FSL_DSPI=y
-CONFIG_SPI_MESON_SPICC=m
-CONFIG_SPI_MESON_SPIFC=m
-CONFIG_SPI_ORION=y
+CONFIG_SPI_FSL_SPI=y
CONFIG_SPI_PL022=y
-CONFIG_SPI_ROCKCHIP=y
-CONFIG_SPI_QUP=y
-CONFIG_SPI_S3C64XX=y
-CONFIG_SPI_SUN6I=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=y
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
CONFIG_SPMI=y
+CONFIG_PPS_CLIENT_LDISC=y
+CONFIG_PPS_CLIENT_GPIO=y
+CONFIG_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_IMX8MM=y
CONFIG_PINCTRL_IMX8MN=y
+CONFIG_PINCTRL_IMX8MP=y
CONFIG_PINCTRL_IMX8MQ=y
CONFIG_PINCTRL_IMX8QM=y
CONFIG_PINCTRL_IMX8QXP=y
CONFIG_PINCTRL_IMX8DXL=y
-CONFIG_PINCTRL_IPQ8074=y
-CONFIG_PINCTRL_MSM8916=y
-CONFIG_PINCTRL_S32V234=y
-CONFIG_PINCTRL_MSM8994=y
-CONFIG_PINCTRL_MSM8996=y
-CONFIG_PINCTRL_MSM8998=y
-CONFIG_PINCTRL_QCS404=y
-CONFIG_PINCTRL_QDF2XXX=y
-CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
-CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SM8150=y
+CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_MB86S7X=y
-CONFIG_GPIO_MPC8XXX=y
CONFIG_GPIO_PL061=y
-CONFIG_GPIO_RCAR=y
-CONFIG_GPIO_UNIPHIER=y
-CONFIG_GPIO_XGENE=y
-CONFIG_GPIO_XGENE_SB=y
+CONFIG_GPIO_FXL6408=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_MAX77620=y
CONFIG_POWER_AVS=y
-CONFIG_ROCKCHIP_IODOMAIN=y
-CONFIG_POWER_RESET_MSM=y
-CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_BRCMSTB=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_BATTERY_SBS=m
-CONFIG_BATTERY_BQ27XXX=y
+CONFIG_BATTERY_BQ27XXX=m
+CONFIG_SENSORS_ADT7410=m
CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SENSORS_GPIO_FAN=y
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_PWM_FAN=m
-CONFIG_SENSORS_RASPBERRYPI_HWMON=m
+CONFIG_SENSORS_SHT3x=m
CONFIG_SENSORS_INA2XX=m
CONFIG_SENSORS_INA3221=m
+CONFIG_SENSORS_TMP102=m
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
@@ -506,68 +418,31 @@ CONFIG_THERMAL_EMULATION=y
CONFIG_IMX_SC_THERMAL=y
CONFIG_DEVICE_THERMAL=y
CONFIG_IMX8MM_THERMAL=y
-CONFIG_QORIQ_THERMAL=y
-CONFIG_ROCKCHIP_THERMAL=m
-CONFIG_RCAR_THERMAL=y
-CONFIG_RCAR_GEN3_THERMAL=y
-CONFIG_ARMADA_THERMAL=y
-CONFIG_BCM2835_THERMAL=m
-CONFIG_BRCMSTB_THERMAL=m
-CONFIG_EXYNOS_THERMAL=y
-CONFIG_TEGRA_BPMP_THERMAL=m
-CONFIG_QCOM_TSENS=y
-CONFIG_UNIPHIER_THERMAL=y
CONFIG_WATCHDOG=y
-CONFIG_ARM_SBSA_WATCHDOG=y
CONFIG_ARM_SP805_WATCHDOG=y
-CONFIG_S3C2410_WATCHDOG=y
+CONFIG_ARM_SBSA_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
-CONFIG_SUNXI_WATCHDOG=m
CONFIG_IMX2_WDT=y
CONFIG_IMX_SC_WDT=y
-CONFIG_MESON_GXBB_WATCHDOG=m
-CONFIG_MESON_WATCHDOG=m
-CONFIG_RENESAS_WDT=y
-CONFIG_UNIPHIER_WATCHDOG=y
-CONFIG_BCM2835_WDT=y
-CONFIG_MFD_ALTERA_SYSMGR=y
-CONFIG_MFD_BD9571MWV=y
-CONFIG_MFD_AXP20X_I2C=y
-CONFIG_MFD_AXP20X_RSB=y
-CONFIG_MFD_EXYNOS_LPASS=m
+CONFIG_XEN_WDT=y
CONFIG_MFD_IMX_AUDIOMIX=y
CONFIG_MFD_HI6421_PMIC=y
-CONFIG_MFD_HI655X_PMIC=y
CONFIG_MFD_MAX77620=y
-CONFIG_MFD_SPMI_PMIC=y
-CONFIG_MFD_RK808=y
-CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_ROHM_BD718XX=y
CONFIG_MFD_PCA9450=y
+CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_BD718XX=y
-CONFIG_REGULATOR_BD9571MWV=y
-CONFIG_REGULATOR_FAN53555=y
CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_HI6421V530=y
-CONFIG_REGULATOR_HI655X=y
-CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_PCA9450=y
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_PWM=y
-CONFIG_REGULATOR_QCOM_RPMH=y
-CONFIG_REGULATOR_QCOM_SMD_RPM=y
-CONFIG_REGULATOR_QCOM_SPMI=y
-CONFIG_REGULATOR_RK808=y
-CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_VCTRL=m
CONFIG_RC_CORE=m
CONFIG_RC_DECODERS=y
CONFIG_RC_DEVICES=y
-CONFIG_IR_MESON=m
-CONFIG_IR_SUNXI=m
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
@@ -582,84 +457,79 @@ CONFIG_VIDEO_MX8_CAPTURE=y
CONFIG_VIDEO_MXC_CAPTURE=y
CONFIG_VIDEO_MXC_CSI_CAMERA=y
CONFIG_MXC_MIPI_CSI=y
-CONFIG_MXC_CAMERA_OV5640_MIPI_V2=y
-CONFIG_VIDEO_SUN6I_CSI=m
+CONFIG_MXC_CAMERA_OV5640_MIPI_V2=m
+CONFIG_VIDEO_ECAM=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
-CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
-CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
-CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
-CONFIG_VIDEO_RENESAS_FCP=m
-CONFIG_VIDEO_RENESAS_VSP1=m
+# crashes on i.MX 8M Plus if loaded as a module
CONFIG_VIDEO_OV5640=y
CONFIG_IMX_DPU_CORE=y
CONFIG_IMX_LCDIF_CORE=y
+CONFIG_IMX_LCDIFV3_CORE=y
CONFIG_DRM=y
+CONFIG_DRM_DP_AUX_CHARDEV=y
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_I2C_CH7006=m
+CONFIG_DRM_I2C_SIL164=m
CONFIG_DRM_I2C_NXP_TDA998X=m
+CONFIG_DRM_I2C_NXP_TDA9950=m
CONFIG_DRM_MALI_DISPLAY=m
-CONFIG_DRM_NOUVEAU=m
-CONFIG_DRM_EXYNOS=m
-CONFIG_DRM_EXYNOS5433_DECON=y
-CONFIG_DRM_EXYNOS7_DECON=y
-CONFIG_DRM_EXYNOS_DSI=y
-# CONFIG_DRM_EXYNOS_DP is not set
-CONFIG_DRM_EXYNOS_HDMI=y
-CONFIG_DRM_EXYNOS_MIC=y
-CONFIG_DRM_ROCKCHIP=m
-CONFIG_ROCKCHIP_ANALOGIX_DP=y
-CONFIG_ROCKCHIP_CDN_DP=y
-CONFIG_ROCKCHIP_DW_HDMI=y
-CONFIG_ROCKCHIP_DW_MIPI_DSI=y
-CONFIG_ROCKCHIP_INNO_HDMI=y
-CONFIG_DRM_RCAR_DU=m
-CONFIG_DRM_SUN4I=m
-CONFIG_DRM_SUN8I_DW_HDMI=m
-CONFIG_DRM_SUN8I_MIXER=m
-CONFIG_DRM_MSM=m
-CONFIG_DRM_TEGRA=m
+CONFIG_DRM_VGEM=m
+CONFIG_DRM_VIRTIO_GPU=m
+CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
CONFIG_DRM_PANEL_WKS_101WX001=y
CONFIG_DRM_NXP_SEIKO_43WVFIG=y
+CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_FSL_IMX_LVDS_BRIDGE=y
+CONFIG_DRM_LVDS_ENCODER=y
+CONFIG_DRM_LONTIUM_LT8912=y
CONFIG_DRM_SII902X=m
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_NWL_MIPI_DSI=y
+CONFIG_DRM_CDNS_MHDP=y
+CONFIG_DRM_CDNS_HDMI=y
+CONFIG_DRM_CDNS_DP=y
+CONFIG_DRM_CDNS_AUDIO=y
CONFIG_DRM_CDNS_HDMI_CEC=y
+CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
+CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
+CONFIG_DRM_DW_HDMI_GP_AUDIO=y
+CONFIG_DRM_DW_HDMI_CEC=y
CONFIG_DRM_ITE_IT6263=y
CONFIG_DRM_IMX=y
CONFIG_DRM_IMX_LCDIF_MUX_DISPLAY=y
CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
CONFIG_DRM_IMX_TVE=y
CONFIG_DRM_IMX_LDB=y
+CONFIG_DRM_IMX8QM_LDB=y
+CONFIG_DRM_IMX8QXP_LDB=y
+CONFIG_DRM_IMX8MP_LDB=y
CONFIG_DRM_IMX_HDMI=y
CONFIG_DRM_IMX_SEC_DSIM=y
-CONFIG_DRM_IMX_CDNS_MHDP=y
+CONFIG_DRM_IMX_CDNS_MHDP=m
CONFIG_DRM_IMX_DCSS=y
-CONFIG_DRM_VC4=m
CONFIG_DRM_ETNAVIV=m
-CONFIG_DRM_HISI_HIBMC=m
-CONFIG_DRM_HISI_KIRIN=m
CONFIG_DRM_MXSFB=y
-CONFIG_DRM_MESON=m
-CONFIG_DRM_PL111=m
-CONFIG_DRM_LIMA=m
-CONFIG_DRM_PANFROST=m
-CONFIG_FB_ARMCLCD=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_TILEBLITTING=y
CONFIG_FB_EFI=y
CONFIG_BACKLIGHT_GENERIC=m
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_LP855X=m
+CONFIG_BACKLIGHT_GPIO=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_SOUND=y
CONFIG_SND=y
-CONFIG_SND_HDA_TEGRA=m
-CONFIG_SND_HDA_CODEC_HDMI=m
+CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_SOC=y
CONFIG_SND_BCM2835_SOC_I2S=m
CONFIG_SND_SOC_FSL_EASRC=y
+CONFIG_SND_SOC_FSL_AUD2HTX=y
CONFIG_SND_IMX_SOC=y
CONFIG_SND_SOC_IMX_AK4458=y
CONFIG_SND_SOC_IMX_AK5558=y
@@ -674,62 +544,76 @@ CONFIG_SND_SOC_IMX_SPDIF=y
CONFIG_SND_SOC_IMX_AUDMIX=y
CONFIG_SND_SOC_IMX_PDM_MIC=y
CONFIG_SND_SOC_IMX_DSP=y
-CONFIG_SND_SOC_IMX_CDNHDMI=y
-CONFIG_SND_MESON_AXG_SOUND_CARD=m
-CONFIG_SND_SOC_ROCKCHIP=m
-CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
-CONFIG_SND_SOC_ROCKCHIP_RT5645=m
-CONFIG_SND_SOC_RK3399_GRU_SOUND=m
-CONFIG_SND_SOC_SAMSUNG=y
-CONFIG_SND_SOC_RCAR=m
+CONFIG_SND_SOC_IMX_CDNHDMI=m
+CONFIG_SND_SOC_IMX_XCVR=y
CONFIG_SND_SOC_SOF_TOPLEVEL=y
CONFIG_SND_SOC_SOF_OF=m
CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
-CONFIG_SND_SOC_SOF_IMX8_SUPPORT=y
-CONFIG_SND_SUN4I_SPDIF=m
-CONFIG_SND_SOC_AK4613=m
-CONFIG_SND_SOC_ES7134=m
-CONFIG_SND_SOC_ES7241=m
-CONFIG_SND_SOC_PCM3168A_I2C=m
-CONFIG_SND_SOC_SGTL5000=m
+CONFIG_SND_SOC_SOF_IMX8_SUPPORT=m
+CONFIG_SND_SOC_SOF_IMX8M_SUPPORT=m
+CONFIG_SND_SOC_BT_SCO=y
+CONFIG_SND_SOC_ICS43432=m
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_SPDIF=m
CONFIG_SND_SOC_TAS571X=m
+CONFIG_SND_SOC_TLV320AIC3X=m
+CONFIG_SND_SOC_WM8904=m
CONFIG_SND_SIMPLE_CARD=y
CONFIG_SND_AUDIO_GRAPH_CARD=y
+CONFIG_HIDRAW=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
CONFIG_I2C_HID=m
CONFIG_USB=y
CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_TEGRA=y
CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_EXYNOS=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_EXYNOS=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_RENESAS_USBHS=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
CONFIG_USB_STORAGE=y
CONFIG_USB_CDNS3=y
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_SUNXI=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC2=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_ISP1760=y
+CONFIG_USB_ISP1760=m
+CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_SIMPLE=y
+CONFIG_USB_SERIAL_CP210X=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_TEST=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_USB_HUB_USB251XB=y
CONFIG_USB_HSIC_USB3503=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MXS_PHY=y
CONFIG_USB_ULPI=y
CONFIG_USB_GADGET=y
-CONFIG_USB_RENESAS_USBHS_UDC=m
-CONFIG_USB_RENESAS_USB3=m
-CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
@@ -750,6 +634,7 @@ CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_ZERO=m
CONFIG_USB_AUDIO=m
CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_TYPEC=y
@@ -766,20 +651,12 @@ CONFIG_MMC_SDHCI_OF_ARASAN=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_CADENCE=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
-CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_F_SDH30=y
-CONFIG_MMC_MESON_GX=y
-CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SPI=y
-CONFIG_MMC_SDHI=y
-CONFIG_MMC_UNIPHIER=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_HI3798CV200=y
CONFIG_MMC_DW_K3=y
-CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MMC_SUNXI=y
-CONFIG_MMC_BCM2835=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -793,194 +670,104 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_EDAC=y
CONFIG_EDAC_GHES=y
+CONFIG_EDAC_SYNOPSYS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_MAX77686=y
-CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_PCF85363=y
CONFIG_RTC_DRV_RX8581=m
-CONFIG_RTC_DRV_S5M=y
CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_PCF2127=y
CONFIG_RTC_DRV_EFI=y
-CONFIG_RTC_DRV_CROS_EC=y
-CONFIG_RTC_DRV_S3C=y
CONFIG_RTC_DRV_PL031=y
-CONFIG_RTC_DRV_SUN6I=y
-CONFIG_RTC_DRV_ARMADA38X=y
-CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_SNVS=y
CONFIG_RTC_DRV_IMX_SC=y
-CONFIG_RTC_DRV_XGENE=y
CONFIG_DMADEVICES=y
-CONFIG_DMA_BCM2835=m
-CONFIG_DMA_SUN6I=m
+CONFIG_BCM_SBA_RAID=m
CONFIG_FSL_EDMA=y
CONFIG_FSL_EDMA_V3=y
-CONFIG_IMX_SDMA=y
-CONFIG_K3_DMA=y
-CONFIG_MV_XOR=y
+CONFIG_IMX_SDMA=m
CONFIG_MV_XOR_V2=y
CONFIG_MXS_DMA=y
CONFIG_PL330_DMA=y
-CONFIG_TEGRA20_APB_DMA=y
-CONFIG_QCOM_BAM_DMA=y
-CONFIG_QCOM_HIDMA_MGMT=y
-CONFIG_QCOM_HIDMA=y
-CONFIG_RCAR_DMAC=y
-CONFIG_RENESAS_USB_DMAC=m
CONFIG_DMATEST=y
CONFIG_UIO=y
CONFIG_UIO_PCI_GENERIC=y
+CONFIG_UIO_IVSHMEM=y
CONFIG_VFIO=y
CONFIG_VFIO_PCI=y
-CONFIG_VFIO_FSL_MC=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
CONFIG_XEN_GNTDEV=y
CONFIG_XEN_GRANT_DEV_ALLOC=y
CONFIG_STAGING=y
+CONFIG_R8188EU=m
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_IMX_CAPTURE=y
CONFIG_ION=y
CONFIG_ION_SYSTEM_HEAP=y
CONFIG_ION_CMA_HEAP=y
-CONFIG_FSL_DPAA2=y
-CONFIG_FSL_DPAA2_ETHSW=y
-CONFIG_FSL_DPAA2_MAC=y
CONFIG_FSL_SDK_DPA=y
CONFIG_FSL_PPFE=y
CONFIG_FSL_PPFE_UTIL_DISABLED=y
-CONFIG_MFD_CROS_EC=y
-CONFIG_CROS_EC_I2C=y
-CONFIG_CROS_EC_SPI=y
-CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_VERSATILE=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_CS2000_CP=y
-CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_COMMON_CLK_PWM=y
-CONFIG_CLK_RASPBERRYPI=m
CONFIG_CLK_IMX8MM=y
CONFIG_CLK_IMX8MN=y
+CONFIG_CLK_IMX8MP=y
CONFIG_CLK_IMX8MQ=y
CONFIG_CLK_IMX8QXP=y
-CONFIG_TI_SCI_CLK=y
-CONFIG_COMMON_CLK_QCOM=y
-CONFIG_QCOM_A53PLL=y
-CONFIG_QCOM_CLK_APCS_MSM8916=y
-CONFIG_QCOM_CLK_SMD_RPM=y
-CONFIG_QCOM_CLK_RPMH=y
-CONFIG_IPQ_GCC_8074=y
-CONFIG_MSM_GCC_8916=y
-CONFIG_MSM_GCC_8994=y
-CONFIG_MSM_MMCC_8996=y
-CONFIG_MSM_GCC_8998=y
-CONFIG_QCS_GCC_404=y
-CONFIG_SDM_GCC_845=y
-CONFIG_SM_GCC_8150=y
CONFIG_HWSPINLOCK=y
-CONFIG_HWSPINLOCK_QCOM=y
CONFIG_ARM_MHU=y
CONFIG_IMX_MBOX=y
CONFIG_PLATFORM_MHU=y
-CONFIG_BCM2835_MBOX=y
-CONFIG_QCOM_APCS_IPC=y
-CONFIG_ROCKCHIP_IOMMU=y
-CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_ARM_SMMU=y
CONFIG_ARM_SMMU_V3=y
-CONFIG_QCOM_IOMMU=y
CONFIG_REMOTEPROC=y
-CONFIG_QCOM_Q6V5_MSS=m
-CONFIG_QCOM_Q6V5_PAS=m
-CONFIG_QCOM_SYSMON=m
+CONFIG_IMX_REMOTEPROC=y
CONFIG_RPMSG_QCOM_GLINK_RPM=y
-CONFIG_RPMSG_QCOM_GLINK_SMEM=m
-CONFIG_RPMSG_QCOM_SMD=y
-CONFIG_RASPBERRYPI_POWER=y
-CONFIG_FSL_MC_DPIO=y
+CONFIG_SOC_BRCMSTB=y
CONFIG_FSL_QIXIS=y
CONFIG_IMX_SCU_SOC=y
-CONFIG_QCOM_GENI_SE=y
-CONFIG_QCOM_GLINK_SSR=m
-CONFIG_QCOM_RPMH=y
-CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_SMD_RPM=y
-CONFIG_QCOM_SMP2P=y
-CONFIG_QCOM_SMSM=y
-CONFIG_ARCH_R8A774A1=y
-CONFIG_ARCH_R8A774C0=y
-CONFIG_ARCH_R8A7795=y
-CONFIG_ARCH_R8A7796=y
-CONFIG_ARCH_R8A77965=y
-CONFIG_ARCH_R8A77970=y
-CONFIG_ARCH_R8A77980=y
-CONFIG_ARCH_R8A77990=y
-CONFIG_ARCH_R8A77995=y
-CONFIG_ROCKCHIP_PM_DOMAINS=y
-CONFIG_ARCH_TEGRA_132_SOC=y
-CONFIG_ARCH_TEGRA_210_SOC=y
-CONFIG_ARCH_TEGRA_186_SOC=y
-CONFIG_ARCH_TEGRA_194_SOC=y
-CONFIG_ARCH_K3_AM6_SOC=y
-CONFIG_ARCH_K3_J721E_SOC=y
-CONFIG_TI_SCI_PM_DOMAINS=y
+CONFIG_SECVIO_SC=y
+CONFIG_SOC_TI=y
+CONFIG_EXTCON_GPIO=y
CONFIG_EXTCON_USB_GPIO=y
-CONFIG_EXTCON_USBC_CROS_EC=y
CONFIG_IIO=y
-CONFIG_EXYNOS_ADC=y
+CONFIG_BMC150_ACCEL=m
+CONFIG_IIO_ST_ACCEL_3AXIS=m
CONFIG_IMX8QXP_ADC=y
-CONFIG_ROCKCHIP_SARADC=m
-CONFIG_IIO_CROS_EC_SENSORS_CORE=m
-CONFIG_IIO_CROS_EC_SENSORS=m
-CONFIG_IIO_CROS_EC_LIGHT_PROX=m
-CONFIG_IIO_CROS_EC_BARO=m
+CONFIG_MAX1363=y
+CONFIG_TI_ADS1015=y
+CONFIG_BMG160=m
+CONFIG_IIO_ST_GYRO_3AXIS=m
+CONFIG_HTU21=m
+CONFIG_SI7020=m
+CONFIG_BMI160_I2C=m
+CONFIG_BMI160_SPI=m
+CONFIG_ISL29125=m
+CONFIG_SI1145=m
+CONFIG_VEML6070=m
+CONFIG_BMC150_MAGN_I2C=m
+CONFIG_BMC150_MAGN_SPI=m
+CONFIG_IIO_ST_MAGN_3AXIS=m
+CONFIG_MS5611=m
+CONFIG_MS5611_I2C=m
+CONFIG_MS5611_SPI=m
CONFIG_PWM=y
-CONFIG_PWM_BCM2835=m
-CONFIG_PWM_CROS_EC=m
CONFIG_PWM_IMX27=y
-CONFIG_PWM_MESON=m
-CONFIG_PWM_RCAR=m
-CONFIG_PWM_ROCKCHIP=y
-CONFIG_PWM_SAMSUNG=y
-CONFIG_PWM_SUN4I=m
-CONFIG_PWM_TEGRA=m
-CONFIG_RESET_TI_SCI=y
-CONFIG_PHY_XGENE=y
-CONFIG_PHY_SUN4I_USB=y
+CONFIG_PHY_MIXEL_LVDS=y
+CONFIG_PHY_MIXEL_LVDS_COMBO=y
+CONFIG_PHY_FSL_IMX8MP_LVDS=y
CONFIG_PHY_MIXEL_MIPI_DPHY=y
-CONFIG_PHY_HI6220_USB=y
-CONFIG_PHY_HISTB_COMBPHY=y
-CONFIG_PHY_HISI_INNO_USB2=y
-CONFIG_PHY_MVEBU_CP110_COMPHY=y
-CONFIG_PHY_QCOM_QMP=m
-CONFIG_PHY_QCOM_QUSB2=m
-CONFIG_PHY_QCOM_USB_HS=y
-CONFIG_PHY_RCAR_GEN3_PCIE=y
-CONFIG_PHY_RCAR_GEN3_USB2=y
-CONFIG_PHY_RCAR_GEN3_USB3=m
-CONFIG_PHY_ROCKCHIP_EMMC=y
-CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
-CONFIG_PHY_ROCKCHIP_INNO_USB2=y
-CONFIG_PHY_ROCKCHIP_PCIE=m
-CONFIG_PHY_ROCKCHIP_TYPEC=y
-CONFIG_PHY_UNIPHIER_USB2=y
-CONFIG_PHY_UNIPHIER_USB3=y
-CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_PHY_SAMSUNG_HDMI_PHY=y
CONFIG_FSL_IMX8_DDR_PMU=y
-CONFIG_HISI_PMU=y
-CONFIG_QCOM_L2_PMU=y
-CONFIG_QCOM_L3_PMU=y
CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_IMX_OCOTP_SCU=y
-CONFIG_QCOM_QFPROM=y
-CONFIG_ROCKCHIP_EFUSE=y
-CONFIG_NVMEM_SUNXI_SID=y
-CONFIG_UNIPHIER_EFUSE=y
-CONFIG_MESON_EFUSE=m
CONFIG_FPGA=y
-CONFIG_FPGA_MGR_STRATIX10_SOC=m
CONFIG_FPGA_BRIDGE=m
CONFIG_ALTERA_FREEZE_BRIDGE=m
CONFIG_FPGA_REGION=m
@@ -989,11 +776,13 @@ CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_MUX_MMIO=y
CONFIG_MXC_SIM=y
+CONFIG_MXC_SIMv2=y
CONFIG_MXC_EMVSIM=y
CONFIG_MXC_MLB150=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
@@ -1004,53 +793,84 @@ CONFIG_FUSE_FS=m
CONFIG_CUSE=m
CONFIG_OVERLAY_FS=m
CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_EFIVAR_FS=y
CONFIG_JFFS2_FS=y
CONFIG_UBIFS_FS=y
-CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_ROOT_NFS=y
-CONFIG_9P_FS=y
+CONFIG_CIFS=m
+CONFIG_9P_FS=m
+CONFIG_NLS_DEFAULT="cp437"
CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
CONFIG_SECURITY=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_TLS=m
CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_OFB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_RMD128=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_RMD256=m
CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_STREEBOG=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
-CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
-CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y
+# CONFIG_RAID6_PQ_BENCHMARK is not set
+CONFIG_INDIRECT_PIO=y
+CONFIG_CRC_CCITT=y
CONFIG_CMA_SIZE_MBYTES=320
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
@@ -1060,3 +880,6 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
CONFIG_MEMTEST=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SOURCE_ETM4X=y
diff --git a/arch/arm64/configs/toradex_defconfig b/arch/arm64/configs/toradex_defconfig
new file mode 100644
index 000000000000..7d1154f0e704
--- /dev/null
+++ b/arch/arm64/configs/toradex_defconfig
@@ -0,0 +1,1076 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_ARCH_MXC=y
+CONFIG_ARM64_VA_BITS_48=y
+CONFIG_SCHED_MC=y
+CONFIG_NUMA=y
+CONFIG_SECCOMP=y
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
+CONFIG_XEN=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ACPI_CPPC_CPUFREQ=m
+CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_IMX_CPUFREQ_DT=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_IMX_DSP=y
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
+CONFIG_IMX_SECO_MU=y
+CONFIG_ACPI=y
+CONFIG_ACPI_APEI=y
+CONFIG_ACPI_APEI_GHES=y
+CONFIG_ACPI_APEI_PCIEAER=y
+CONFIG_ACPI_APEI_MEMORY_FAILURE=y
+CONFIG_ACPI_APEI_EINJ=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_CRYPTO_SM4_ARM64_CE=m
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_NHPOLY1305_NEON=m
+CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_KSM=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_ZSMALLOC=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_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_LLC2=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_CBS=y
+CONFIG_NET_SCH_TAPRIO=y
+CONFIG_NET_SCH_MQPRIO=y
+CONFIG_NET_CLS_BASIC=y
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_TSN=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=y
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_VXCAN=m
+CONFIG_CAN_SLCAN=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_CAN_MCP25XXFD=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_3WIRE=y
+CONFIG_BT_HCIUART_BCM=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_WILINK=m
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_RFKILL_GPIO=m
+CONFIG_NET_9P=m
+CONFIG_NET_9P_VIRTIO=m
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=y
+CONFIG_PCI_IOV=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCI_IMX6_HOST=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BRCMSTB_GISB_ARB=y
+CONFIG_SIMPLE_PM_BUS=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_SST25L=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_DENALI_DT=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_MTD_UBI=y
+CONFIG_ZRAM=y
+CONFIG_ZRAM_WRITEBACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_XEN_BLKDEV_BACKEND=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_NVME=y
+CONFIG_SENSORS_FXOS8700=m
+CONFIG_SENSORS_FXAS2100X=m
+CONFIG_SRAM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=m
+CONFIG_TI_ST=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_HISI_SAS=y
+CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_SCSI_MPT3SAS=m
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=m
+CONFIG_AHCI_CEVA=y
+CONFIG_SATA_SIL24=y
+CONFIG_PATA_PLATFORM=y
+CONFIG_PATA_OF_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=y
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+CONFIG_FEC=y
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+CONFIG_E1000=m
+CONFIG_E1000E=m
+CONFIG_IGB=m
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETERION is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MICREL_PHY=y
+CONFIG_NXP_TJA11XX_PHY=m
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_ASYNC=m
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_AX88179_178A is not set
+# CONFIG_USB_NET_CDC_NCM is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_PCIE=m
+CONFIG_MWIFIEX_USB=m
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_NXP is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_RTL_CARDS is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_WLAN_VENDOR_QUANTENNA is not set
+CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_IVSHMEM_NET=m
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_SNVS_PWRKEY=y
+CONFIG_KEYBOARD_IMX_SC_PWRKEY=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_COLIBRI_VF50=m
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPL3115=m
+CONFIG_INPUT_ISL29023=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=m
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS_I2C_INFINEON=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_IMX=y
+CONFIG_I2C_IMX_LPI2C=y
+CONFIG_I2C_RK3X=y
+CONFIG_I2C_RPBUS=y
+CONFIG_XEN_I2C_BACKEND=y
+CONFIG_I2C_SLAVE=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_LPSPI=y
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_SPI_NXP_FLEXSPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_FSL_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
+CONFIG_SPMI=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_IMX8MM=y
+CONFIG_PINCTRL_IMX8MN=y
+CONFIG_PINCTRL_IMX8MP=y
+CONFIG_PINCTRL_IMX8MQ=y
+CONFIG_PINCTRL_IMX8QM=y
+CONFIG_PINCTRL_IMX8QXP=y
+CONFIG_PINCTRL_IMX8DXL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_MB86S7X=y
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_FXL6408=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_MAX77620=y
+CONFIG_POWER_AVS=y
+CONFIG_POWER_RESET_BRCMSTB=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_BATTERY_SBS=m
+CONFIG_BATTERY_BQ27XXX=m
+CONFIG_SENSORS_ADT7410=m
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_SHT3x=m
+CONFIG_SENSORS_INA2XX=m
+CONFIG_SENSORS_INA3221=m
+CONFIG_SENSORS_TMP102=m
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_IMX_SC_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_IMX8MM_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_DW_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_IMX_SC_WDT=y
+CONFIG_XEN_WDT=y
+CONFIG_MFD_IMX_AUDIOMIX=y
+CONFIG_MFD_HI6421_PMIC=y
+CONFIG_MFD_MAX77620=y
+CONFIG_MFD_ROHM_BD718XX=y
+CONFIG_MFD_PCA9450=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_BD718XX=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_PCA9450=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_VCTRL=m
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_DVB_NET is not set
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MUX=m
+CONFIG_VIDEO_MX8_CAPTURE=y
+CONFIG_VIDEO_MXC_CAPTURE=y
+CONFIG_VIDEO_MXC_CSI_CAMERA=y
+CONFIG_MXC_MIPI_CSI=y
+CONFIG_MXC_CAMERA_OV5640_MIPI_V2=m
+CONFIG_VIDEO_ECAM=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_OV5640=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA18250 is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MSI001 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_FC0011 is not set
+# CONFIG_MEDIA_TUNER_FC0012 is not set
+# CONFIG_MEDIA_TUNER_FC0013 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
+# CONFIG_MEDIA_TUNER_E4000 is not set
+# CONFIG_MEDIA_TUNER_FC2580 is not set
+# CONFIG_MEDIA_TUNER_M88RS6000T is not set
+# CONFIG_MEDIA_TUNER_TUA9001 is not set
+# CONFIG_MEDIA_TUNER_SI2157 is not set
+# CONFIG_MEDIA_TUNER_IT913X is not set
+# CONFIG_MEDIA_TUNER_R820T is not set
+# CONFIG_MEDIA_TUNER_MXL301RF is not set
+# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
+# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+# CONFIG_DVB_STV090x is not set
+# CONFIG_DVB_STV0910 is not set
+# CONFIG_DVB_STV6110x is not set
+# CONFIG_DVB_STV6111 is not set
+# CONFIG_DVB_MXL5XX is not set
+# CONFIG_DVB_M88DS3103 is not set
+# CONFIG_DVB_DRXK is not set
+# CONFIG_DVB_TDA18271C2DD is not set
+# CONFIG_DVB_SI2165 is not set
+# CONFIG_DVB_MN88472 is not set
+# CONFIG_DVB_MN88473 is not set
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24123 is not set
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_ZL10036 is not set
+# CONFIG_DVB_ZL10039 is not set
+# CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_STV6110 is not set
+# CONFIG_DVB_STV0900 is not set
+# CONFIG_DVB_TDA8083 is not set
+# CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_TDA8261 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_TUNER_CX24113 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_CX24117 is not set
+# CONFIG_DVB_CX24120 is not set
+# CONFIG_DVB_SI21XX is not set
+# CONFIG_DVB_TS2020 is not set
+# CONFIG_DVB_DS3000 is not set
+# CONFIG_DVB_MB86A16 is not set
+# CONFIG_DVB_TDA10071 is not set
+# CONFIG_DVB_SP8870 is not set
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_CX22700 is not set
+# CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_S5H1432 is not set
+# CONFIG_DVB_DRXD is not set
+# CONFIG_DVB_L64781 is not set
+# CONFIG_DVB_TDA1004X is not set
+# CONFIG_DVB_NXT6000 is not set
+# CONFIG_DVB_MT352 is not set
+# CONFIG_DVB_ZL10353 is not set
+# CONFIG_DVB_DIB3000MB is not set
+# CONFIG_DVB_DIB3000MC is not set
+# CONFIG_DVB_DIB7000M is not set
+# CONFIG_DVB_DIB7000P is not set
+# CONFIG_DVB_DIB9000 is not set
+# CONFIG_DVB_TDA10048 is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DVB_EC100 is not set
+# CONFIG_DVB_STV0367 is not set
+# CONFIG_DVB_CXD2820R is not set
+# CONFIG_DVB_CXD2841ER is not set
+# CONFIG_DVB_RTL2830 is not set
+# CONFIG_DVB_RTL2832 is not set
+# CONFIG_DVB_SI2168 is not set
+# CONFIG_DVB_ZD1301_DEMOD is not set
+# CONFIG_DVB_CXD2880 is not set
+# CONFIG_DVB_VES1820 is not set
+# CONFIG_DVB_TDA10021 is not set
+# CONFIG_DVB_TDA10023 is not set
+# CONFIG_DVB_STV0297 is not set
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_DVB_LGDT3305 is not set
+# CONFIG_DVB_LGDT3306A is not set
+# CONFIG_DVB_LG2160 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_AU8522_DTV is not set
+# CONFIG_DVB_AU8522_V4L is not set
+# CONFIG_DVB_S5H1411 is not set
+# CONFIG_DVB_S921 is not set
+# CONFIG_DVB_DIB8000 is not set
+# CONFIG_DVB_MB86A20S is not set
+# CONFIG_DVB_TC90522 is not set
+# CONFIG_DVB_MN88443X is not set
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+# CONFIG_DVB_DRX39XYJ is not set
+# CONFIG_DVB_LNBH25 is not set
+# CONFIG_DVB_LNBH29 is not set
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_LNBP22 is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_ISL6423 is not set
+# CONFIG_DVB_A8293 is not set
+# CONFIG_DVB_LGS8GL5 is not set
+# CONFIG_DVB_LGS8GXX is not set
+# CONFIG_DVB_ATBM8830 is not set
+# CONFIG_DVB_TDA665x is not set
+# CONFIG_DVB_IX2505V is not set
+# CONFIG_DVB_M88RS2000 is not set
+# CONFIG_DVB_AF9033 is not set
+# CONFIG_DVB_HORUS3A is not set
+# CONFIG_DVB_ASCOT2E is not set
+# CONFIG_DVB_HELENE is not set
+# CONFIG_DVB_CXD2099 is not set
+# CONFIG_DVB_SP2 is not set
+CONFIG_IMX_DPU_CORE=y
+CONFIG_IMX_LCDIF_CORE=y
+CONFIG_IMX_LCDIFV3_CORE=y
+CONFIG_DRM=y
+CONFIG_DRM_DP_AUX_CHARDEV=y
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_I2C_CH7006=m
+CONFIG_DRM_I2C_SIL164=m
+CONFIG_DRM_I2C_NXP_TDA998X=m
+CONFIG_DRM_I2C_NXP_TDA9950=m
+CONFIG_DRM_MALI_DISPLAY=m
+CONFIG_DRM_VGEM=m
+CONFIG_DRM_VIRTIO_GPU=m
+CONFIG_DRM_PANEL_LVDS=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
+CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+CONFIG_DRM_PANEL_WKS_101WX001=y
+CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_FSL_IMX_LVDS_BRIDGE=y
+CONFIG_DRM_LVDS_ENCODER=y
+CONFIG_DRM_LONTIUM_LT8912=y
+CONFIG_DRM_SII902X=m
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_DRM_NWL_MIPI_DSI=y
+CONFIG_DRM_CDNS_MHDP=y
+CONFIG_DRM_CDNS_HDMI=y
+CONFIG_DRM_CDNS_DP=y
+CONFIG_DRM_CDNS_AUDIO=y
+CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
+CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
+CONFIG_DRM_DW_HDMI_GP_AUDIO=y
+CONFIG_DRM_DW_HDMI_CEC=y
+CONFIG_DRM_ITE_IT6263=y
+CONFIG_DRM_IMX=y
+CONFIG_DRM_IMX_LCDIF_MUX_DISPLAY=y
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
+CONFIG_DRM_IMX_TVE=y
+CONFIG_DRM_IMX_LDB=y
+CONFIG_DRM_IMX8QM_LDB=y
+CONFIG_DRM_IMX8QXP_LDB=y
+CONFIG_DRM_IMX8MP_LDB=y
+CONFIG_DRM_IMX_HDMI=y
+CONFIG_DRM_IMX_SEC_DSIM=y
+CONFIG_DRM_IMX_DCSS=y
+CONFIG_DRM_IMX_CDNS_MHDP=m
+CONFIG_DRM_ETNAVIV=m
+CONFIG_DRM_MXSFB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_EFI=y
+CONFIG_BACKLIGHT_GENERIC=m
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_LP855X=m
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_EASRC=y
+CONFIG_SND_SOC_FSL_AUD2HTX=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_AK4458=y
+CONFIG_SND_SOC_IMX_AK5558=y
+CONFIG_SND_SOC_IMX_AK4497=y
+CONFIG_SND_SOC_IMX_WM8960=y
+CONFIG_SND_SOC_IMX_WM8524=y
+CONFIG_SND_SOC_IMX_CS42888=y
+CONFIG_SND_SOC_IMX_MICFIL=y
+CONFIG_SND_SOC_IMX_RPMSG=y
+CONFIG_SND_SOC_IMX_MQS=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_AUDMIX=y
+CONFIG_SND_SOC_IMX_PDM_MIC=y
+CONFIG_SND_SOC_IMX_DSP=y
+CONFIG_SND_SOC_IMX_CDNHDMI=m
+CONFIG_SND_SOC_IMX_XCVR=y
+CONFIG_SND_SOC_SOF_TOPLEVEL=y
+CONFIG_SND_SOC_SOF_OF=m
+CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
+CONFIG_SND_SOC_SOF_IMX8_SUPPORT=m
+CONFIG_SND_SOC_SOF_IMX8M_SUPPORT=m
+CONFIG_SND_SOC_BT_SCO=y
+CONFIG_SND_SOC_ICS43432=m
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_SPDIF=m
+CONFIG_SND_SOC_TAS571X=m
+CONFIG_SND_SOC_TLV320AIC3X=m
+CONFIG_SND_SOC_WM8904=m
+CONFIG_SND_SOC_NAU8822=m
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_AUDIO_GRAPH_CARD=y
+CONFIG_HIDRAW=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_I2C_HID=m
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_HCD_TEST_MODE=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_ISP1760=m
+CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_SIMPLE=y
+CONFIG_USB_SERIAL_CP210X=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_TEST=m
+CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_USB_HUB_USB251XB=y
+CONFIG_USB_HSIC_USB3503=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_UVC=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_TYPEC=y
+CONFIG_TYPEC_TCPM=y
+CONFIG_TYPEC_TCPCI=y
+CONFIG_TYPEC_SWITCH_GPIO=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+CONFIG_MMC_SDHCI_OF_ESDHC=y
+CONFIG_MMC_SDHCI_CADENCE=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MMC_SDHCI_F_SDH30=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_EXYNOS=y
+CONFIG_MMC_DW_HI3798CV200=y
+CONFIG_MMC_DW_K3=y
+CONFIG_MMC_SDHCI_XENON=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_EDAC=y
+CONFIG_EDAC_GHES=y
+CONFIG_EDAC_SYNOPSYS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_PCF85363=y
+CONFIG_RTC_DRV_RX8581=m
+CONFIG_RTC_DRV_DS3232=y
+CONFIG_RTC_DRV_PCF2127=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_RTC_DRV_IMX_SC=y
+CONFIG_DMADEVICES=y
+CONFIG_BCM_SBA_RAID=m
+CONFIG_FSL_EDMA=y
+CONFIG_FSL_EDMA_V3=y
+CONFIG_IMX_SDMA=m
+CONFIG_MV_XOR_V2=y
+CONFIG_MXS_DMA=y
+CONFIG_PL330_DMA=y
+CONFIG_DMATEST=y
+CONFIG_UIO=y
+CONFIG_UIO_PCI_GENERIC=y
+CONFIG_UIO_IVSHMEM=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_STAGING=y
+CONFIG_R8188EU=m
+CONFIG_STAGING_MEDIA=y
+CONFIG_VIDEO_IMX_CAPTURE=y
+CONFIG_ION=y
+CONFIG_ION_SYSTEM_HEAP=y
+CONFIG_ION_CMA_HEAP=y
+CONFIG_FSL_SDK_DPA=y
+CONFIG_FSL_PPFE=y
+CONFIG_FSL_PPFE_UTIL_DISABLED=y
+CONFIG_COMMON_CLK_VERSATILE=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_CS2000_CP=y
+CONFIG_COMMON_CLK_PWM=y
+CONFIG_CLK_IMX8MM=y
+CONFIG_CLK_IMX8MN=y
+CONFIG_CLK_IMX8MP=y
+CONFIG_CLK_IMX8MQ=y
+CONFIG_CLK_IMX8QXP=y
+CONFIG_HWSPINLOCK=y
+CONFIG_ARM_MHU=y
+CONFIG_IMX_MBOX=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_V3=y
+CONFIG_REMOTEPROC=y
+CONFIG_IMX_REMOTEPROC=y
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
+CONFIG_SOC_BRCMSTB=y
+CONFIG_FSL_QIXIS=y
+CONFIG_IMX_SCU_SOC=y
+CONFIG_SECVIO_SC=y
+CONFIG_SOC_TI=y
+CONFIG_EXTCON_GPIO=y
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_BMC150_ACCEL=m
+CONFIG_IIO_ST_ACCEL_3AXIS=m
+CONFIG_IMX8QXP_ADC=y
+CONFIG_MAX1363=y
+CONFIG_TI_ADS1015=y
+CONFIG_BMG160=m
+CONFIG_IIO_ST_GYRO_3AXIS=m
+CONFIG_HTU21=m
+CONFIG_SI7020=m
+CONFIG_BMI160_I2C=m
+CONFIG_BMI160_SPI=m
+CONFIG_ISL29125=m
+CONFIG_SI1145=m
+CONFIG_VEML6070=m
+CONFIG_BMC150_MAGN_I2C=m
+CONFIG_BMC150_MAGN_SPI=m
+CONFIG_IIO_ST_MAGN_3AXIS=m
+CONFIG_MS5611=m
+CONFIG_MS5611_I2C=m
+CONFIG_MS5611_SPI=m
+CONFIG_PWM=y
+CONFIG_PWM_IMX27=y
+CONFIG_PHY_MIXEL_LVDS=y
+CONFIG_PHY_MIXEL_LVDS_COMBO=y
+CONFIG_PHY_FSL_IMX8MP_LVDS=y
+CONFIG_PHY_MIXEL_MIPI_DPHY=y
+CONFIG_PHY_SAMSUNG_HDMI_PHY=y
+CONFIG_FSL_IMX8_DDR_PMU=y
+CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_NVMEM_IMX_OCOTP_SCU=y
+CONFIG_FPGA=y
+CONFIG_FPGA_BRIDGE=m
+CONFIG_ALTERA_FREEZE_BRIDGE=m
+CONFIG_FPGA_REGION=m
+CONFIG_OF_FPGA_REGION=m
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=y
+CONFIG_MXC_SIM=y
+CONFIG_MXC_SIMv2=y
+CONFIG_MXC_EMVSIM=y
+CONFIG_MXC_MLB150=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_OVERLAY_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_EFIVAR_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_9P_FS=m
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_TLS=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CFB=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_OFB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_STREEBOG=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
+# CONFIG_RAID6_PQ_BENCHMARK is not set
+CONFIG_INDIRECT_PIO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CMA_SIZE_MBYTES=1376
+CONFIG_CMA_SIZE_PERCENTAGE=25
+CONFIG_CMA_SIZE_SEL_MIN=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_MEMTEST=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SOURCE_ETM4X=y
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index e69af4d2c303..00ddc2302108 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -144,6 +144,7 @@ struct imx_ahci_priv {
struct clk *per_clk4;
struct clk *per_clk5;
void __iomem *phy_base;
+ struct clk *sata_ext;
int clkreq_gpio;
struct regmap *gpr;
bool no_device;
@@ -910,10 +911,14 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
if (ret)
return ret;
- ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+ ret = clk_prepare_enable(imxpriv->sata_ext);
if (ret < 0)
goto disable_regulator;
+ ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+ if (ret < 0)
+ goto disable_ext;
+
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
/*
* set PHY Paremeters, two steps to configure the GPR13,
@@ -957,6 +962,8 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
disable_clk:
clk_disable_unprepare(imxpriv->sata_ref_clk);
+disable_ext:
+ clk_disable_unprepare(imxpriv->sata_ext);
disable_regulator:
ahci_platform_disable_regulators(hpriv);
@@ -996,6 +1003,8 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
clk_disable_unprepare(imxpriv->sata_ref_clk);
+ clk_disable_unprepare(imxpriv->sata_ext);
+
ahci_platform_disable_regulators(hpriv);
}
@@ -1479,6 +1488,12 @@ static int imx_ahci_probe(struct platform_device *pdev)
return PTR_ERR(imxpriv->sata_clk);
}
+ imxpriv->sata_ext = devm_clk_get(dev, "sata_ext");
+ if (IS_ERR(imxpriv->sata_ext)) {
+ dev_err(dev, "can't get sata_ext clock.\n");
+ return PTR_ERR(imxpriv->sata_ext);
+ }
+
imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
if (IS_ERR(imxpriv->sata_ref_clk)) {
dev_err(dev, "can't get sata_ref clock.\n");
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index e080640f028e..41d27dd7d74c 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -78,6 +78,8 @@ static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
clk_gate2_do_hardware(gate, enable);
imx_sema4_mutex_unlock(amp_power_mutex);
+#else
+ clk_gate2_do_hardware(gate, enable);
#endif
} else {
clk_gate2_do_hardware(gate, enable);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 8f317f4554a1..a66cb9a4add2 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -454,7 +454,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
hws[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_hw_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2);
hws[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_hw_gate_dis_flags("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4, CLK_IS_CRITICAL);
- hws[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_hw_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
+ hws[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_hw_gate_dis_flags("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5, CLK_IS_CRITICAL);
hws[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_hw_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
hws[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_hw_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
@@ -704,7 +704,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
hws[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_hw_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
hws[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_hw_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
hws[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_hw_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
- hws[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_hw_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
+ hws[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_hw_divider2_flags("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT);
hws[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_hw_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6);
hws[IMX7D_IPG_ROOT_CLK] = imx_clk_hw_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT);
hws[IMX7D_DRAM_ROOT_DIV] = imx_clk_hw_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
@@ -877,12 +877,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX7D_MIPI_CSI_ROOT_SRC]->clk, hws[IMX7D_PLL_SYS_PFD3_CLK]->clk);
- if (imx_src_is_m4_enabled()) {
- clk_set_parent(hws[IMX7D_ARM_M4_ROOT_SRC]->clk, hws[IMX7D_PLL_SYS_MAIN_240M_CLK]->clk);
- clk_prepare_enable(hws[IMX7D_ARM_M4_ROOT_CLK]->clk);
- clk_prepare_enable(hws[IMX7D_UART2_ROOT_CLK]->clk);
- }
-
/* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
clk_set_parent(hws[IMX7D_GPT1_ROOT_SRC]->clk, hws[IMX7D_OSC_24M_CLK]->clk);
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 7fb34c2a803e..ccbace3f6e35 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -146,6 +146,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER);
imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER);
+ imx_clk_scu("adc1_clk", IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER);
imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
index fc2e0fe03bdd..ad76fbe9ad62 100644
--- a/drivers/clk/imx/clk-pfd.c
+++ b/drivers/clk/imx/clk-pfd.c
@@ -69,6 +69,8 @@ static void clk_pfd_do_shared_clks(struct clk_hw *hw, bool enable)
clk_pfd_do_hardware(pfd, enable);
imx_sema4_mutex_unlock(amp_power_mutex);
+#else
+ clk_pfd_do_hardware(pfd, enable);
#endif
} else {
clk_pfd_do_hardware(pfd, enable);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index fd4d4d809d61..b90ae869ed0a 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -128,6 +128,8 @@ static void clk_pllv3_do_shared_clks(struct clk_hw *hw, bool enable)
clk_pllv3_do_hardware(hw, enable);
imx_sema4_mutex_unlock(amp_power_mutex);
+#else
+ clk_pllv3_do_hardware(hw, enable);
#endif
} else {
clk_pllv3_do_hardware(hw, enable);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index b940f68c978c..6acd41c29c9a 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -300,6 +300,14 @@ static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *p
reg, shift, width, 0, &imx_ccm_lock);
}
+static inline struct clk_hw *imx_clk_hw_divider2_flags(const char *name,
+ const char *parent,
+ void __iomem *reg, u8 shift, u8 width, unsigned long flags)
+{
+ return clk_hw_register_divider(NULL, name, parent,
+ flags, reg, shift, width, 0, &imx_ccm_lock);
+}
+
static inline struct clk *imx_clk_divider2_flags(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 width,
unsigned long flags)
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3a70580b304b..2ff36b7633f8 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -109,6 +109,8 @@ static const struct of_device_id blacklist[] __initconst = {
{ .compatible = "calxeda,ecx-2000", },
{ .compatible = "fsl,imx7d", },
+ { .compatible = "fsl,imx7s", },
+
{ .compatible = "fsl,imx8mq", },
{ .compatible = "fsl,imx8mm", },
{ .compatible = "fsl,imx8mn", },
diff --git a/drivers/dma/pxp/pxp_dma_v3.c b/drivers/dma/pxp/pxp_dma_v3.c
index 9e46621cc37a..c2aa04b79e74 100644
--- a/drivers/dma/pxp/pxp_dma_v3.c
+++ b/drivers/dma/pxp/pxp_dma_v3.c
@@ -7974,14 +7974,14 @@ static int pxp_probe(struct platform_device *pdev)
goto exit;
}
+ pxp_clk_enable(pxp);
+
pxp_soft_reset(pxp);
pxp_writel(0x0, HW_PXP_CTRL);
/* Initialize DMA engine */
err = pxp_dma_init(pxp);
if (err < 0)
goto exit;
-
- pxp_clk_enable(pxp);
pxp_soft_reset(pxp);
/* Initialize PXP Interrupt */
diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c
index 98b5afa5b615..b5435b341553 100644
--- a/drivers/extcon/extcon-usb-gpio.c
+++ b/drivers/extcon/extcon-usb-gpio.c
@@ -20,7 +20,7 @@
#include <linux/workqueue.h>
#include <linux/pinctrl/consumer.h>
-#define USB_GPIO_DEBOUNCE_MS 20 /* ms */
+#define USB_GPIO_DEBOUNCE_MS 100 /* ms */
struct usb_extcon_info {
struct device *dev;
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index 82ded67594ed..ef0b97de5d01 100755
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -157,7 +157,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
{ "can", IMX_SC_R_CAN_0, 3, true, 0 },
{ "ftm", IMX_SC_R_FTM_0, 2, true, 0 },
{ "lpi2c", IMX_SC_R_I2C_0, 5, true, 0 },
- { "adc", IMX_SC_R_ADC_0, 1, true, 0 },
+ { "adc", IMX_SC_R_ADC_0, 2, true, 0 },
{ "lcd", IMX_SC_R_LCD_0, 1, true, 0 },
{ "lcd-pll", IMX_SC_R_ELCDIF_PLL, 1, true, 0 },
{ "lcd0-pwm", IMX_SC_R_LCD_0_PWM_0, 1, true, 0 },
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index deea0a292664..60fe745758e0 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -863,6 +863,12 @@ config GPIO_ADNP
enough to represent all pins, but the driver will assume a
register layout for 64 pins (8 registers).
+config GPIO_FXL6408
+ tristate "FXL6408 I2C GPIO expander"
+ help
+ This option enables support for 8 GPIOs found
+ on the Fairchild Semiconductor FXL6408.
+
config GPIO_GW_PLD
tristate "Gateworks PLD GPIO Expander"
depends on OF_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 30e93c76995d..d62218ba921a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
+obj-$(CONFIG_GPIO_FXL6408) += gpio-fxl6408.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
diff --git a/drivers/gpio/gpio-fxl6408.c b/drivers/gpio/gpio-fxl6408.c
new file mode 100644
index 000000000000..22d193c4d9d5
--- /dev/null
+++ b/drivers/gpio/gpio-fxl6408.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2016 Broadcom Limited.
+ *
+ * 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; version 2 of the License.
+ */
+
+/**
+ * DOC: FXL6408 I2C to GPIO expander.
+ *
+ * This chip has has 8 GPIO lines out of it, and is controlled by an
+ * I2C bus (a pair of lines), providing 4x expansion of GPIO lines.
+ * It also provides an interrupt line out for notifying of
+ * statechanges.
+ *
+ * Any preconfigured state will be left in place until the GPIO lines
+ * get activated. At power on, everything is treated as an input.
+ *
+ * Documentation can be found at:
+ * https://www.fairchildsemi.com/datasheets/FX/FXL6408.pdf
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/of_platform.h>
+
+#define FXL6408_DEVICE_ID 0x01
+# define FXL6408_RST_INT BIT(1)
+# define FXL6408_SW_RST BIT(0)
+
+/* Bits set here indicate that the GPIO is an output. */
+#define FXL6408_IO_DIR 0x03
+/* Bits set here, when the corresponding bit of IO_DIR is set, drive
+ * the output high instead of low.
+ */
+#define FXL6408_OUTPUT 0x05
+/* Bits here make the output High-Z, instead of the OUTPUT value. */
+#define FXL6408_OUTPUT_HIGH_Z 0x07
+/* Bits here define the expected input state of the GPIO.
+ * INTERRUPT_STAT bits will be set when the INPUT transitions away
+ * from this value.
+ */
+#define FXL6408_INPUT_DEFAULT_STATE 0x09
+/* Bits here enable either pull up or pull down according to
+ * FXL6408_PULL_DOWN.
+ */
+#define FXL6408_PULL_ENABLE 0x0b
+/* Bits set here (when the corresponding PULL_ENABLE is set) enable a
+ * pull-up instead of a pull-down.
+ */
+#define FXL6408_PULL_UP 0x0d
+/* Returns the current status (1 = HIGH) of the input pins. */
+#define FXL6408_INPUT_STATUS 0x0f
+/* Mask of pins which can generate interrupts. */
+#define FXL6408_INTERRUPT_MASK 0x11
+/* Mask of pins which have generated an interrupt. Cleared on read. */
+#define FXL6408_INTERRUPT_STAT 0x13
+
+struct fxl6408_chip {
+ struct gpio_chip gpio_chip;
+ struct i2c_client *client;
+ struct mutex i2c_lock;
+
+ /* Caches of register values so we don't have to read-modify-write. */
+ u8 reg_io_dir;
+ u8 reg_output;
+};
+
+static int fxl6408_gpio_direction_input(struct gpio_chip *gc, unsigned off)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+ mutex_lock(&chip->i2c_lock);
+ chip->reg_io_dir &= ~BIT(off);
+ i2c_smbus_write_byte_data(chip->client, FXL6408_IO_DIR,
+ chip->reg_io_dir);
+ mutex_unlock(&chip->i2c_lock);
+
+ return 0;
+}
+
+static int fxl6408_gpio_direction_output(struct gpio_chip *gc,
+ unsigned off, int val)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+ mutex_lock(&chip->i2c_lock);
+ chip->reg_io_dir |= BIT(off);
+ i2c_smbus_write_byte_data(chip->client, FXL6408_IO_DIR,
+ chip->reg_io_dir);
+ mutex_unlock(&chip->i2c_lock);
+
+ return 0;
+}
+
+static int fxl6408_gpio_get_direction(struct gpio_chip *gc, unsigned off)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+ return (chip->reg_io_dir & BIT(off)) == 0;
+}
+
+static int fxl6408_gpio_get_value(struct gpio_chip *gc, unsigned off)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+ u8 reg;
+
+ if (fxl6408_gpio_get_direction(gc, off) == 0)
+ {
+ reg = chip->reg_output;
+ } else {
+ mutex_lock(&chip->i2c_lock);
+ reg = i2c_smbus_read_byte_data(chip->client, FXL6408_INPUT_STATUS);
+ mutex_unlock(&chip->i2c_lock);
+ }
+ return (reg & BIT(off)) != 0;
+}
+
+static void fxl6408_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+ mutex_lock(&chip->i2c_lock);
+
+ if (val)
+ chip->reg_output |= BIT(off);
+ else
+ chip->reg_output &= ~BIT(off);
+
+ i2c_smbus_write_byte_data(chip->client, FXL6408_OUTPUT,
+ chip->reg_output);
+ mutex_unlock(&chip->i2c_lock);
+}
+
+
+static void fxl6408_gpio_set_multiple(struct gpio_chip *gc,
+ unsigned long *mask, unsigned long *bits)
+{
+ struct fxl6408_chip *chip = gpiochip_get_data(gc);
+ mutex_lock(&chip->i2c_lock);
+ chip->reg_output = (chip->reg_output & ~mask[0]) | bits[0];
+ i2c_smbus_write_byte_data(chip->client, FXL6408_OUTPUT,
+ chip->reg_output);
+ mutex_unlock(&chip->i2c_lock);
+}
+
+static int fxl6408_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct fxl6408_chip *chip;
+ struct gpio_chip *gc;
+ unsigned int val;
+ int ret;
+ u8 device_id;
+
+ /* Check the device ID register to see if it's responding.
+ * This also clears RST_INT as a side effect, so we won't get
+ * the "we've been power cycled" interrupt once we enable
+ * interrupts.
+ */
+ device_id = i2c_smbus_read_byte_data(client, FXL6408_DEVICE_ID);
+ if (device_id < 0) {
+ dev_err(dev, "FXL6408 probe returned %d\n", device_id);
+ return device_id;
+ } else if (device_id >> 5 != 5) {
+ dev_err(dev, "FXL6408 probe returned DID: 0x%02x\n", device_id);
+ return -ENODEV;
+ }
+
+ /* Disable High-Z of outputs, so that our OUTPUT updates
+ * actually take effect.
+ */
+ i2c_smbus_write_byte_data(client, FXL6408_OUTPUT_HIGH_Z, 0);
+
+ chip = devm_kzalloc(dev, sizeof(struct fxl6408_chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ chip->client = client;
+ mutex_init(&chip->i2c_lock);
+
+ /* if configured, set initial output state and direction,
+ * otherwise read them from the chip */
+ if (of_property_read_u32(dev->of_node, "inital_io_dir", &val)) {
+ chip->reg_io_dir = i2c_smbus_read_byte_data(client, FXL6408_IO_DIR);
+ } else {
+ chip->reg_io_dir = val & 0xff;
+ i2c_smbus_write_byte_data(client, FXL6408_IO_DIR, chip->reg_io_dir);
+ }
+ if (of_property_read_u32(dev->of_node, "inital_output", &val)) {
+ chip->reg_output = i2c_smbus_read_byte_data(client, FXL6408_OUTPUT);
+ } else {
+ chip->reg_output = val & 0xff;
+ i2c_smbus_write_byte_data(client, FXL6408_OUTPUT, chip->reg_output);
+ }
+
+ gc = &chip->gpio_chip;
+ gc->direction_input = fxl6408_gpio_direction_input;
+ gc->direction_output = fxl6408_gpio_direction_output;
+ gc->get_direction = fxl6408_gpio_get_direction;
+ gc->get = fxl6408_gpio_get_value;
+ gc->set = fxl6408_gpio_set_value;
+ gc->set_multiple = fxl6408_gpio_set_multiple;
+ gc->can_sleep = true;
+
+ gc->base =-1;
+ gc->ngpio = 8;
+ gc->label = chip->client->name;
+ gc->parent = dev;
+ gc->owner = THIS_MODULE;
+
+ ret = gpiochip_add_data(gc, chip);
+ if (ret)
+ return ret;
+
+ i2c_set_clientdata(client, chip);
+ return 0;
+}
+
+static int fxl6408_remove(struct i2c_client *client)
+{
+ struct fxl6408_chip *chip = i2c_get_clientdata(client);
+
+ gpiochip_remove(&chip->gpio_chip);
+
+ return 0;
+}
+
+static const struct of_device_id fxl6408_dt_ids[] = {
+ { .compatible = "fcs,fxl6408" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, fxl6408_dt_ids);
+
+static const struct i2c_device_id fxl6408_id[] = {
+ { "fxl6408", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, fxl6408_id);
+
+static struct i2c_driver fxl6408_driver = {
+ .driver = {
+ .name = "fxl6408",
+ .of_match_table = fxl6408_dt_ids,
+ },
+ .probe = fxl6408_probe,
+ .remove = fxl6408_remove,
+ .id_table = fxl6408_id,
+};
+
+module_i2c_driver(fxl6408_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("GPIO expander driver for FXL6408");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index f7efac9a347b..ebdc6ea09573 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -7,6 +7,7 @@
// Authors: Daniel Mack, Juergen Beisert.
// Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+#include <linux/moduleparam.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -32,6 +33,10 @@
#define IMX_SC_PAD_WAKEUP_OFF 0
#endif
+static bool noclearirq = false;
+module_param(noclearirq, bool, 0);
+MODULE_PARM_DESC(noclearirq, "do not clear IRQ mask/status on probe");
+
enum mxc_gpio_hwtype {
IMX1_GPIO, /* runs on i.mx1 */
IMX21_GPIO, /* runs on i.mx21 and i.mx27 */
@@ -583,6 +588,37 @@ static void mxc_gpio_free(struct gpio_chip *chip, unsigned offset)
pm_runtime_put(chip->parent);
}
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+/*
+ * parse pad wakeup info from dtb, each pad has to provide
+ * <pin_id, type, line>, these info should be put in each
+ * gpio node and with a "pad-wakeup-num" to indicate the
+ * total lines are with pad wakeup enabled.
+ */
+static int setup_pad_wakeup(struct mxc_gpio_port *port,
+ struct device_node *np)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < port->pad_wakeup_num; i++) {
+ if ((err = of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 0, &port->pad_wakeup[i].pin_id)))
+ return err;
+ if ((err = of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 1, &port->pad_wakeup[i].type)))
+ return err;
+ if ((err = of_property_read_u32_index(np, "pad-wakeup",
+ i * 3 + 2, &port->pad_wakeup[i].line)))
+ return err;
+ }
+ err = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_PAD, true);
+
+
+ return err;
+}
+#endif
+
static int mxc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -590,9 +626,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
int irq_count;
int irq_base = 0;
int err;
-#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
- int i;
-#endif
mxc_gpio_get_hw(pdev);
@@ -632,30 +665,18 @@ static int mxc_gpio_probe(struct platform_device *pdev)
}
#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
- /*
- * parse pad wakeup info from dtb, each pad has to provide
- * <pin_id, type, line>, these info should be put in each
- * gpio node and with a "pad-wakeup-num" to indicate the
- * total lines are with pad wakeup enabled.
- */
- if (!of_property_read_u32(np, "pad-wakeup-num", &port->pad_wakeup_num)) {
- if (port->pad_wakeup_num != 0) {
- if (!gpio_ipc_handle) {
- err = imx_scu_get_handle(&gpio_ipc_handle);
- if (err)
- return err;
- }
- for (i = 0; i < port->pad_wakeup_num; i++) {
- of_property_read_u32_index(np, "pad-wakeup",
- i * 3 + 0, &port->pad_wakeup[i].pin_id);
- of_property_read_u32_index(np, "pad-wakeup",
- i * 3 + 1, &port->pad_wakeup[i].type);
- of_property_read_u32_index(np, "pad-wakeup",
- i * 3 + 2, &port->pad_wakeup[i].line);
- }
- err = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_PAD, true);
+ if (!of_property_read_u32(np, "pad-wakeup-num", &port->pad_wakeup_num)
+ && port->pad_wakeup_num != 0) {
+ if (!gpio_ipc_handle) {
+ err = imx_scu_get_handle(&gpio_ipc_handle);
if (err)
- dev_warn(&pdev->dev, "Enable irq failed, GPIO pad wakeup NOT supported\n");
+ goto out_clk_disable;
+ }
+
+ err = setup_pad_wakeup(port, np);
+ if (err) {
+ dev_warn(&pdev->dev, "Enable irq failed, GPIO pad wakeup NOT supported\n");
+ goto out_clk_disable;
}
}
#endif
@@ -667,11 +688,13 @@ static int mxc_gpio_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
err = pm_runtime_get_sync(&pdev->dev);
if (err < 0)
- goto out_pm_dis;
+ goto out_pm_disable;
/* disable the interrupt and clear the status */
- writel(0, port->base + GPIO_IMR);
- writel(~0, port->base + GPIO_ISR);
+ if (!noclearirq) {
+ writel(0, port->base + GPIO_IMR);
+ writel(~0, port->base + GPIO_ISR);
+ }
if (mxc_gpio_hwtype == IMX21_GPIO) {
/*
@@ -697,7 +720,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
port->base + GPIO_GDIR, NULL,
BGPIOF_READ_OUTPUT_REG_SET);
if (err)
- goto out_bgio;
+ goto out_pm_put;
if (of_property_read_bool(np, "gpio-ranges")) {
port->gc.request = gpiochip_generic_request;
@@ -718,19 +741,19 @@ static int mxc_gpio_probe(struct platform_device *pdev)
err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);
if (err)
- goto out_bgio;
+ goto out_pm_put;
irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id());
if (irq_base < 0) {
err = irq_base;
- goto out_bgio;
+ goto out_pm_put;
}
port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
&irq_domain_simple_ops, NULL);
if (!port->domain) {
err = -ENODEV;
- goto out_bgio;
+ goto out_pm_put;
}
/* gpio-mxc can be a generic irq chip */
@@ -745,12 +768,15 @@ static int mxc_gpio_probe(struct platform_device *pdev)
return 0;
-out_pm_dis:
- pm_runtime_disable(&pdev->dev);
- clk_disable_unprepare(port->clk);
out_irqdomain_remove:
irq_domain_remove(port->domain);
-out_bgio:
+out_pm_put:
+ pm_runtime_put(&pdev->dev);
+out_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP
+out_clk_disable:
+#endif
clk_disable_unprepare(port->clk);
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
return err;
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 1a20991ba88e..9e3778cce1ed 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -74,6 +74,14 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
to DP++. This is used with the i.MX6 imx-ldb
driver. You are likely to say N here.
+config DRM_LONTIUM_LT8912
+ tristate "Lontium LT8912 MIPI-DSI to LVDS and HDMI/MHL bridge"
+ depends on OF
+ select DRM_KMS_HELPER
+ select REGMAP_I2C
+ help
+ Lontium LT8912 MIPI-DSI to LVDS and HDMI/MHL bridge chip driver.
+
config DRM_SEC_MIPI_DSIM
tristate "Samsung MIPI DSIM Bridge"
depends on OF
@@ -183,6 +191,8 @@ source "drivers/gpu/drm/bridge/cadence/Kconfig"
source "drivers/gpu/drm/bridge/synopsys/Kconfig"
+source "drivers/gpu/drm/bridge/sn65dsi83/Kconfig"
+
config DRM_ITE_IT6263
tristate "ITE IT6263 LVDS/HDMI bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 103466b50b2a..9016ea806307 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
obj-$(CONFIG_DRM_FSL_IMX_LVDS_BRIDGE) += fsl-imx-ldb.o
obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
+obj-$(CONFIG_DRM_LONTIUM_LT8912) += lt8912.o
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
@@ -23,3 +24,4 @@ obj-y += synopsys/
obj-$(CONFIG_DRM_ITE_IT6263) += it6263.o
obj-$(CONFIG_DRM_SEC_MIPI_DSIM) += sec-dsim.o
obj-$(CONFIG_DRM_NXP_SEIKO_43WVFIG) += nxp-seiko-43wvfig.o
+obj-$(CONFIG_DRM_I2C_SN65DSI83) += sn65dsi83/
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
index 07700e494857..b9677ef4c23d 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
@@ -251,6 +251,7 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_set_plugged_cb);
static enum drm_connector_status
cdns_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
+ struct edid *edid;
struct cdns_mhdp_device *mhdp =
container_of(connector, struct cdns_mhdp_device, connector.base);
enum drm_connector_status result;
@@ -259,15 +260,21 @@ cdns_hdmi_connector_detect(struct drm_connector *connector, bool force)
hpd = cdns_mhdp_read_hpd(mhdp);
- if (hpd == 1)
+ if (hpd == 1) {
/* Cable Connected */
result = connector_status_connected;
- else if (hpd == 0)
+ } else if (hpd == 0) {
/* Cable Disconnedted */
result = connector_status_disconnected;
- else {
+ } else if (mhdp->ddc) {
+ edid = drm_get_edid(connector, mhdp->ddc);
+ if (drm_edid_is_valid(edid))
+ result = connector_status_connected;
+ else
+ result = connector_status_disconnected;
+ } else {
/* Cable status unknown */
- DRM_INFO("Unknow cable status, hdp=%u\n", hpd);
+ DRM_INFO("Unknow cable status, hpd=%u\n", hpd);
result = connector_status_unknown;
}
@@ -289,8 +296,15 @@ static int cdns_hdmi_connector_get_modes(struct drm_connector *connector)
int num_modes = 0;
struct edid *edid;
- edid = drm_do_get_edid(&mhdp->connector.base,
- cdns_hdmi_get_edid_block, mhdp);
+ /*
+ * Check if optional regular DDC I2C bus should be used.
+ * Fall-back to using IP/firmware integrated one.
+ */
+ if (mhdp->ddc)
+ edid = drm_get_edid(&mhdp->connector.base, mhdp->ddc);
+ else
+ edid = drm_do_get_edid(&mhdp->connector.base,
+ cdns_hdmi_get_edid_block, mhdp);
if (edid) {
dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
edid->header[0], edid->header[1],
@@ -545,6 +559,7 @@ static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data)
static void cdns_hdmi_parse_dt(struct cdns_mhdp_device *mhdp)
{
struct device_node *of_node = mhdp->dev->of_node;
+ struct device_node *ddc_phandle;
int ret;
ret = of_property_read_u32(of_node, "lane-mapping", &mhdp->lane_mapping);
@@ -553,6 +568,17 @@ static void cdns_hdmi_parse_dt(struct cdns_mhdp_device *mhdp)
dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n");
}
dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping);
+
+ /* get optional regular DDC I2C bus */
+ ddc_phandle = of_parse_phandle(of_node, "ddc-i2c-bus", 0);
+ if (ddc_phandle) {
+ mhdp->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
+ if (mhdp->ddc)
+ dev_info(mhdp->dev, "Connector's ddc i2c bus found\n");
+ else
+ ret = -EPROBE_DEFER;
+ of_node_put(ddc_phandle);
+ }
}
static int __cdns_hdmi_probe(struct platform_device *pdev,
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 7aa789c35882..83ba7ba78f35 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -79,6 +79,13 @@ dumb_vga_connector_detect(struct drm_connector *connector, bool force)
struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
/*
+ * If I2C bus for DDC is not defined, asume that the cable
+ * is always connected.
+ */
+ if (PTR_ERR(vga->ddc) == -ENODEV)
+ return connector_status_connected;
+
+ /*
* Even if we have an I2C bus, we can't assume that the cable
* is disconnected if drm_probe_ddc fails. Some cables don't
* wire the DDC pins, or the I2C bus might not be working at
diff --git a/drivers/gpu/drm/bridge/lt8912.c b/drivers/gpu/drm/bridge/lt8912.c
new file mode 100644
index 000000000000..af49911d447b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/lt8912.c
@@ -0,0 +1,730 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Copyright 2019 Toradex AG
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_of.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_mipi_dsi.h>
+
+#define HOTPLUG_DEBOUNCE_MS 1100
+
+struct lt8912 {
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+ struct drm_display_mode mode;
+ struct device *dev;
+ struct mipi_dsi_device *dsi;
+ struct device_node *host_node;
+ u8 num_dsi_lanes;
+ u8 channel_id;
+ unsigned int irq;
+ u8 sink_is_hdmi;
+ struct regmap *regmap[3];
+ struct gpio_desc *hpd_gpio;
+ struct gpio_desc *reset_n;
+ struct i2c_adapter *ddc; /* optional regular DDC I2C bus */
+ struct delayed_work hotplug_work;
+};
+
+static int lt8912_attach_dsi(struct lt8912 *lt);
+
+static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
+{
+ return container_of(b, struct lt8912, bridge);
+}
+
+static inline struct lt8912 *connector_to_lt8912(struct drm_connector *c)
+{
+ return container_of(c, struct lt8912, connector);
+}
+
+/* LT8912 MIPI to HDMI & LVDS REG setting - 20180115.txt */
+static void lt8912_init(struct lt8912 *lt)
+{
+ u8 lanes = lt->dsi->lanes;
+ const struct drm_display_mode *mode = &lt->mode;
+ u32 hactive, hfp, hsync, hbp, vfp, vsync, vbp, htotal, vtotal;
+ unsigned int hsync_activehigh, vsync_activehigh, reg;
+ unsigned int version[2];
+
+ dev_info(lt->dev, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
+ /* TODO: lvds output init */
+
+ hactive = mode->hdisplay;
+ hfp = mode->hsync_start - mode->hdisplay;
+ hsync = mode->hsync_end - mode->hsync_start;
+ hsync_activehigh = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
+ hbp = mode->htotal - mode->hsync_end;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vsync = mode->vsync_end - mode->vsync_start;
+ vsync_activehigh = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
+ vbp = mode->vtotal - mode->vsync_end;
+ htotal = mode->htotal;
+ vtotal = mode->vtotal;
+
+ regmap_read(lt->regmap[0], 0x00, &version[0]);
+ regmap_read(lt->regmap[0], 0x01, &version[1]);
+
+ dev_info(lt->dev, "LT8912 ID: %02x, %02x\n",
+ version[0], version[1]);
+
+ /* DigitalClockEn */
+ regmap_write(lt->regmap[0], 0x08, 0xff);
+ regmap_write(lt->regmap[0], 0x09, 0xff);
+ regmap_write(lt->regmap[0], 0x0a, 0xff);
+ regmap_write(lt->regmap[0], 0x0b, 0x7c);
+ regmap_write(lt->regmap[0], 0x0c, 0xff);
+
+ /* TxAnalog */
+ regmap_write(lt->regmap[0], 0x31, 0xa1);
+ regmap_write(lt->regmap[0], 0x32, 0xa1);
+ regmap_write(lt->regmap[0], 0x33, 0x03);
+ regmap_write(lt->regmap[0], 0x37, 0x00);
+ regmap_write(lt->regmap[0], 0x38, 0x22);
+ regmap_write(lt->regmap[0], 0x60, 0x82);
+
+ /* CbusAnalog */
+ regmap_write(lt->regmap[0], 0x39, 0x45);
+ regmap_write(lt->regmap[0], 0x3a, 0x00);
+ regmap_write(lt->regmap[0], 0x3b, 0x00);
+
+ /* HDMIPllAnalog */
+ regmap_write(lt->regmap[0], 0x44, 0x31);
+ regmap_write(lt->regmap[0], 0x55, 0x44);
+ regmap_write(lt->regmap[0], 0x57, 0x01);
+ regmap_write(lt->regmap[0], 0x5a, 0x02);
+
+ /* MIPIAnalog */
+ regmap_write(lt->regmap[0], 0x3e, 0xce);
+ regmap_write(lt->regmap[0], 0x3f, 0xd4);
+ regmap_write(lt->regmap[0], 0x41, 0x3c);
+
+ /* MipiBasicSet */
+ regmap_write(lt->regmap[1], 0x12, 0x04);
+ regmap_write(lt->regmap[1], 0x13, lanes % 4);
+ regmap_write(lt->regmap[1], 0x14, 0x00);
+
+ regmap_write(lt->regmap[1], 0x15, 0x00);
+ regmap_write(lt->regmap[1], 0x1a, 0x03);
+ regmap_write(lt->regmap[1], 0x1b, 0x03);
+
+ /* MIPIDig */
+ regmap_write(lt->regmap[1], 0x10, 0x01);
+ regmap_write(lt->regmap[1], 0x11, 0x0a);
+ regmap_write(lt->regmap[1], 0x18, hsync);
+ regmap_write(lt->regmap[1], 0x19, vsync);
+ regmap_write(lt->regmap[1], 0x1c, hactive % 0x100);
+ regmap_write(lt->regmap[1], 0x1d, hactive >> 8);
+
+ regmap_write(lt->regmap[1], 0x2f, 0x0c);
+
+ regmap_write(lt->regmap[1], 0x34, htotal % 0x100);
+ regmap_write(lt->regmap[1], 0x35, htotal >> 8);
+ regmap_write(lt->regmap[1], 0x36, vtotal % 0x100);
+ regmap_write(lt->regmap[1], 0x37, vtotal >> 8);
+ regmap_write(lt->regmap[1], 0x38, vbp % 0x100);
+ regmap_write(lt->regmap[1], 0x39, vbp >> 8);
+ regmap_write(lt->regmap[1], 0x3a, vfp % 0x100);
+ regmap_write(lt->regmap[1], 0x3b, vfp >> 8);
+ regmap_write(lt->regmap[1], 0x3c, hbp % 0x100);
+ regmap_write(lt->regmap[1], 0x3d, hbp >> 8);
+ regmap_write(lt->regmap[1], 0x3e, hfp % 0x100);
+ regmap_write(lt->regmap[1], 0x3f, hfp >> 8);
+ regmap_read(lt->regmap[0], 0xab, &reg);
+ reg &= 0xfc;
+ reg |= (hsync_activehigh < 1) | vsync_activehigh;
+ regmap_write(lt->regmap[0], 0xab, reg);
+
+ /* DDSConfig */
+ regmap_write(lt->regmap[1], 0x4e, 0x6a);
+ regmap_write(lt->regmap[1], 0x4f, 0xad);
+ regmap_write(lt->regmap[1], 0x50, 0xf3);
+ regmap_write(lt->regmap[1], 0x51, 0x80);
+
+ regmap_write(lt->regmap[1], 0x1f, 0x5e);
+ regmap_write(lt->regmap[1], 0x20, 0x01);
+ regmap_write(lt->regmap[1], 0x21, 0x2c);
+ regmap_write(lt->regmap[1], 0x22, 0x01);
+ regmap_write(lt->regmap[1], 0x23, 0xfa);
+ regmap_write(lt->regmap[1], 0x24, 0x00);
+ regmap_write(lt->regmap[1], 0x25, 0xc8);
+ regmap_write(lt->regmap[1], 0x26, 0x00);
+ regmap_write(lt->regmap[1], 0x27, 0x5e);
+ regmap_write(lt->regmap[1], 0x28, 0x01);
+ regmap_write(lt->regmap[1], 0x29, 0x2c);
+ regmap_write(lt->regmap[1], 0x2a, 0x01);
+ regmap_write(lt->regmap[1], 0x2b, 0xfa);
+ regmap_write(lt->regmap[1], 0x2c, 0x00);
+ regmap_write(lt->regmap[1], 0x2d, 0xc8);
+ regmap_write(lt->regmap[1], 0x2e, 0x00);
+ regmap_write(lt->regmap[1], 0x42, 0x64);
+ regmap_write(lt->regmap[1], 0x43, 0x00);
+ regmap_write(lt->regmap[1], 0x44, 0x04);
+ regmap_write(lt->regmap[1], 0x45, 0x00);
+ regmap_write(lt->regmap[1], 0x46, 0x59);
+ regmap_write(lt->regmap[1], 0x47, 0x00);
+ regmap_write(lt->regmap[1], 0x48, 0xf2);
+ regmap_write(lt->regmap[1], 0x49, 0x06);
+ regmap_write(lt->regmap[1], 0x4a, 0x00);
+ regmap_write(lt->regmap[1], 0x4b, 0x72);
+ regmap_write(lt->regmap[1], 0x4c, 0x45);
+ regmap_write(lt->regmap[1], 0x4d, 0x00);
+ regmap_write(lt->regmap[1], 0x52, 0x08);
+ regmap_write(lt->regmap[1], 0x53, 0x00);
+ regmap_write(lt->regmap[1], 0x54, 0xb2);
+ regmap_write(lt->regmap[1], 0x55, 0x00);
+ regmap_write(lt->regmap[1], 0x56, 0xe4);
+ regmap_write(lt->regmap[1], 0x57, 0x0d);
+ regmap_write(lt->regmap[1], 0x58, 0x00);
+ regmap_write(lt->regmap[1], 0x59, 0xe4);
+ regmap_write(lt->regmap[1], 0x5a, 0x8a);
+ regmap_write(lt->regmap[1], 0x5b, 0x00);
+ regmap_write(lt->regmap[1], 0x5c, 0x34);
+ regmap_write(lt->regmap[1], 0x1e, 0x4f);
+ regmap_write(lt->regmap[1], 0x51, 0x00);
+
+ regmap_write(lt->regmap[0], 0xb2, lt->sink_is_hdmi);
+
+ /* Audio Disable */
+ regmap_write(lt->regmap[2], 0x06, 0x00);
+ regmap_write(lt->regmap[2], 0x07, 0x00);
+
+ regmap_write(lt->regmap[2], 0x34, 0xd2);
+
+ regmap_write(lt->regmap[2], 0x3c, 0x41);
+
+ /* MIPIRxLogicRes */
+ regmap_write(lt->regmap[0], 0x03, 0x7f);
+ usleep_range(10000, 20000);
+ regmap_write(lt->regmap[0], 0x03, 0xff);
+
+ regmap_write(lt->regmap[1], 0x51, 0x80);
+ usleep_range(10000, 20000);
+ regmap_write(lt->regmap[1], 0x51, 0x00);
+}
+
+static void lt8912_wakeup(struct lt8912 *lt)
+{
+ gpiod_direction_output(lt->reset_n, 1);
+ msleep(120);
+ gpiod_direction_output(lt->reset_n, 0);
+
+ regmap_write(lt->regmap[0], 0x08, 0xff); /* enable clk gating */
+ regmap_write(lt->regmap[0], 0x41, 0x3c); /* MIPI Rx Power On */
+ regmap_write(lt->regmap[0], 0x05, 0xfb); /* DDS logical reset */
+ regmap_write(lt->regmap[0], 0x05, 0xff);
+ regmap_write(lt->regmap[0], 0x03, 0x7f); /* MIPI RX logical reset */
+ usleep_range(10000, 20000);
+ regmap_write(lt->regmap[0], 0x03, 0xff);
+ regmap_write(lt->regmap[0], 0x32, 0xa1);
+ regmap_write(lt->regmap[0], 0x33, 0x03);
+}
+
+static void lt8912_sleep(struct lt8912 *lt)
+{
+ regmap_write(lt->regmap[0], 0x32, 0xa0);
+ regmap_write(lt->regmap[0], 0x33, 0x00); /* Disable HDMI output. */
+ regmap_write(lt->regmap[0], 0x41, 0x3d); /* MIPI Rx Power Down. */
+ regmap_write(lt->regmap[0], 0x08, 0x00); /* disable DDS clk. */
+
+ gpiod_direction_output(lt->reset_n, 1);
+}
+
+static enum drm_connector_status
+lt8912_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct lt8912 *lt = connector_to_lt8912(connector);
+ enum drm_connector_status hpd, hpd_last;
+ int timeout = 0;
+
+ hpd = connector_status_unknown;
+ do {
+ hpd_last = hpd;
+ hpd = gpiod_get_value_cansleep(lt->hpd_gpio) ?
+ connector_status_connected : connector_status_disconnected;
+ msleep(20);
+ timeout += 20;
+ } while ((hpd_last != hpd) && (timeout < 500));
+
+ return hpd;
+}
+
+static const struct drm_connector_funcs lt8912_connector_funcs = {
+ .detect = lt8912_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void lt8912_hotplug_work_func(struct work_struct *work)
+{
+ struct lt8912 *lt;
+
+ lt = container_of(work, struct lt8912, hotplug_work.work);
+
+ if (lt->bridge.dev)
+ drm_helper_hpd_irq_event(lt->bridge.dev);
+
+}
+
+static irqreturn_t lt8912_hpd_irq_thread(int irq, void *arg)
+{
+ struct lt8912 *lt = arg;
+
+ mod_delayed_work(system_wq, &lt->hotplug_work,
+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+ return IRQ_HANDLED;
+}
+
+static struct drm_encoder *
+lt8912_connector_best_encoder(struct drm_connector *connector)
+{
+ struct lt8912 *lt = connector_to_lt8912(connector);
+
+ return lt->bridge.encoder;
+}
+
+static int lt8912_connector_get_modes(struct drm_connector *connector)
+{
+ struct lt8912 *lt = connector_to_lt8912(connector);
+ struct edid *edid;
+ struct display_timings *timings;
+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ int i, ret, num_modes = 0;
+
+ /* Check if optional DDC I2C bus should be used. */
+ if (lt->ddc) {
+ edid = drm_get_edid(connector, lt->ddc);
+ if (edid) {
+ drm_connector_update_edid_property(connector,
+ edid);
+ num_modes = drm_add_edid_modes(connector, edid);
+ lt->sink_is_hdmi = !!drm_detect_hdmi_monitor(edid);
+ kfree(edid);
+ }
+ if (num_modes == 0) {
+ dev_warn(lt->dev, "failed to get display timings from EDID\n");
+ return 0;
+ }
+ } else { /* if not EDID, use dtb timings */
+ timings = of_get_display_timings(lt->dev->of_node);
+
+ if (!timings || timings->num_timings == 0) {
+ dev_err(lt->dev, "failed to get display timings from dtb\n");
+ return 0;
+ }
+
+ for (i = 0; i < timings->num_timings; i++) {
+ struct drm_display_mode *mode;
+ struct videomode vm;
+
+ if (videomode_from_timings(timings, &vm, i))
+ continue;
+
+ mode = drm_mode_create(connector->dev);
+ drm_display_mode_from_videomode(&vm, mode);
+ mode->type = DRM_MODE_TYPE_DRIVER;
+
+ if (timings->native_mode == i)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_set_name(mode);
+ drm_mode_probed_add(connector, mode);
+ num_modes++;
+ }
+ if (num_modes == 0) {
+ dev_err(lt->dev, "failed to get display modes from dtb\n");
+ return 0;
+ }
+ }
+
+ connector->display_info.bus_flags = DRM_BUS_FLAG_DE_LOW |
+ DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+ ret = drm_display_info_set_bus_formats(&connector->display_info,
+ &bus_format, 1);
+
+ if (ret)
+ return ret;
+
+ return num_modes;
+}
+
+static enum drm_mode_status lt8912_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ if (mode->clock > 150000)
+ return MODE_CLOCK_HIGH;
+
+ if (mode->hdisplay > 1920)
+ return MODE_BAD_HVALUE;
+
+ if (mode->vdisplay > 1080)
+ return MODE_BAD_VVALUE;
+
+ return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
+ .get_modes = lt8912_connector_get_modes,
+ .best_encoder = lt8912_connector_best_encoder,
+ .mode_valid = lt8912_connector_mode_valid,
+};
+
+static void lt8912_bridge_post_disable(struct drm_bridge *bridge)
+{
+ struct lt8912 *lt = bridge_to_lt8912(bridge);
+
+ lt8912_sleep(lt);
+}
+
+static void lt8912_bridge_enable(struct drm_bridge *bridge)
+{
+ struct lt8912 *lt = bridge_to_lt8912(bridge);
+
+ lt8912_init(lt);
+}
+
+static void lt8912_bridge_pre_enable(struct drm_bridge *bridge)
+{
+ struct lt8912 *lt = bridge_to_lt8912(bridge);
+
+ lt8912_wakeup(lt);
+}
+
+static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adj)
+{
+ struct lt8912 *lt = bridge_to_lt8912(bridge);
+
+ drm_mode_copy(&lt->mode, adj);
+}
+
+static int lt8912_bridge_attach(struct drm_bridge *bridge)
+{
+ struct lt8912 *lt = bridge_to_lt8912(bridge);
+ struct drm_connector *connector = &lt->connector;
+ int ret;
+
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+ ret = drm_connector_init(bridge->dev, connector,
+ &lt8912_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA);
+ if (ret) {
+ dev_err(lt->dev, "failed to initialize connector\n");
+ return ret;
+ }
+
+ drm_connector_helper_add(connector, &lt8912_connector_helper_funcs);
+ drm_connector_attach_encoder(connector, bridge->encoder);
+
+ if (!bridge->encoder) {
+ dev_err(lt->dev, "Parent encoder object not found");
+ return -ENODEV;
+ }
+
+ ret = lt8912_attach_dsi(lt);
+
+ if (!ret && irqd_irq_disabled(irq_get_irq_data(lt->irq)))
+ enable_irq(lt->irq);
+
+ return ret;
+}
+
+static const struct drm_bridge_funcs lt8912_bridge_funcs = {
+ .attach = lt8912_bridge_attach,
+ .mode_set = lt8912_bridge_mode_set,
+ .pre_enable = lt8912_bridge_pre_enable,
+ .enable = lt8912_bridge_enable,
+ .post_disable = lt8912_bridge_post_disable,
+};
+
+static const struct regmap_config lt8912_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0xff,
+};
+
+static int lt8912_i2c_init(struct lt8912 *lt,
+ struct i2c_client *client)
+{
+ struct i2c_board_info info[] = {
+ { I2C_BOARD_INFO("lt8912p0", 0x48), },
+ { I2C_BOARD_INFO("lt8912p1", 0x49), },
+ { I2C_BOARD_INFO("lt8912p2", 0x4a), }
+ };
+ struct regmap *regmap;
+ unsigned int i;
+ int ret;
+
+ if (!lt || !client)
+ return -ENODEV;
+
+ ret = i2c_smbus_read_byte(client);
+ if (ret < 0) {
+ dev_err(lt->dev, "Failed to access device %s at address %02x",
+ info[0].type, info[0].addr);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(info); i++) {
+ if (i > 0) {
+ client = i2c_new_dummy(client->adapter, info[i].addr);
+ if (!client)
+ return -ENODEV;
+ }
+ regmap = devm_regmap_init_i2c(client, &lt8912_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(lt->dev,
+ "Failed to initialize regmap: %d\n", ret);
+ return ret;
+ }
+
+ lt->regmap[i] = regmap;
+ }
+
+ return 0;
+}
+
+int lt8912_attach_dsi(struct lt8912 *lt)
+{
+ struct device *dev = lt->dev;
+ struct mipi_dsi_host *host;
+ struct mipi_dsi_device *dsi;
+ int ret = 0;
+ const struct mipi_dsi_device_info info = {
+ .type = "lt8912",
+ .channel = lt->channel_id,
+ .node = NULL,
+ };
+
+ host = of_find_mipi_dsi_host_by_node(lt->host_node);
+ if (!host) {
+ dev_err(dev, "failed to find dsi host\n");
+ return -EPROBE_DEFER;
+ }
+
+ dsi = mipi_dsi_device_register_full(host, &info);
+ if (IS_ERR(dsi)) {
+ dev_err(dev, "failed to create dsi device\n");
+ ret = PTR_ERR(dsi);
+ goto err_dsi_device;
+ }
+
+ lt->dsi = dsi;
+
+ dsi->lanes = lt->num_dsi_lanes;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET;
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach dsi to host\n");
+ goto err_dsi_attach;
+ }
+
+ return 0;
+
+err_dsi_attach:
+ mipi_dsi_device_unregister(dsi);
+err_dsi_device:
+ return ret;
+}
+
+void lt8912_detach_dsi(struct lt8912 *lt)
+{
+ mipi_dsi_detach(lt->dsi);
+ mipi_dsi_device_unregister(lt->dsi);
+}
+
+
+static int lt8912_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ struct device *dev = &i2c->dev;
+ struct lt8912 *lt;
+ struct device_node *ddc_phandle;
+ struct device_node *endpoint;
+ unsigned int irq_flags;
+ int ret = 0;
+
+ if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
+ DRM_ERROR("device doesn't support I2C\n");
+ return -ENODEV;
+ }
+
+ lt = devm_kzalloc(dev, sizeof(*lt), GFP_KERNEL);
+ if (!lt)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, lt);
+ lt->dev = dev;
+
+ /* get optional regular DDC I2C bus */
+ ddc_phandle = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
+ if (ddc_phandle) {
+ lt->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
+ of_node_put(ddc_phandle);
+ if (!(lt->ddc))
+ return -EPROBE_DEFER;
+ }
+
+ lt->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
+ if (IS_ERR(lt->hpd_gpio)) {
+ ret = PTR_ERR(lt->hpd_gpio);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to get hpd gpio: %d\n", ret);
+ goto put_i2c_ddc;
+ }
+
+ lt->irq = gpiod_to_irq(lt->hpd_gpio);
+ if (lt->irq == -ENXIO) {
+ dev_err(dev, "failed to get hpd irq\n");
+ ret = -ENODEV;
+ goto put_i2c_ddc;
+ }
+ if (lt->irq < 0) {
+ dev_err(dev, "failed to get hpd irq, %i\n", lt->irq);
+ ret = lt->irq;
+ goto put_i2c_ddc;
+ }
+
+ INIT_DELAYED_WORK(&lt->hotplug_work, lt8912_hotplug_work_func);
+
+ irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+ ret = devm_request_threaded_irq(dev, lt->irq,
+ NULL,
+ lt8912_hpd_irq_thread,
+ irq_flags, "lt8912_hpd", lt);
+ if (ret) {
+ dev_err(dev, "failed to request irq: %d\n", ret);
+ ret = -ENODEV;
+ goto put_i2c_ddc;
+ }
+
+ disable_irq(lt->irq);
+
+ lt->reset_n = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
+ if (IS_ERR(lt->reset_n)) {
+ ret = PTR_ERR(lt->reset_n);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to request reset GPIO: %d\n", ret);
+ goto put_i2c_ddc;
+ }
+
+ ret = lt8912_i2c_init(lt, i2c);
+ if (ret)
+ goto put_i2c_ddc;
+
+ /* TODO: interrupt handing */
+
+ lt->num_dsi_lanes = 4;
+ lt->channel_id = 1;
+
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (!endpoint) {
+ ret = -ENODEV;
+ goto put_i2c_ddc;
+ }
+
+ lt->host_node = of_graph_get_remote_port_parent(endpoint);
+ of_node_put(endpoint);
+ if (!lt->host_node) {
+ ret = -ENODEV;
+ goto put_i2c_ddc;
+ }
+
+ lt->bridge.funcs = &lt8912_bridge_funcs;
+ lt->bridge.of_node = dev->of_node;
+ drm_bridge_add(&lt->bridge);
+
+ return 0;
+
+put_i2c_ddc:
+ i2c_put_adapter(lt->ddc);
+ return ret;
+}
+
+static int lt8912_remove(struct i2c_client *i2c)
+{
+ struct lt8912 *lt = i2c_get_clientdata(i2c);
+
+ cancel_delayed_work_sync(&lt->hotplug_work);
+
+ lt8912_sleep(lt);
+ mipi_dsi_detach(lt->dsi);
+ drm_bridge_remove(&lt->bridge);
+ of_node_put(lt->host_node);
+ i2c_put_adapter(lt->ddc);
+
+ return 0;
+}
+
+static const struct i2c_device_id lt8912_i2c_ids[] = {
+ { "lt8912", 0 },
+ { }
+};
+
+static const struct of_device_id lt8912_of_match[] = {
+ { .compatible = "lontium,lt8912" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lt8912_of_match);
+
+static struct mipi_dsi_driver lt8912_driver = {
+ .driver.name = "lt8912",
+};
+
+static struct i2c_driver lt8912_i2c_driver = {
+ .driver = {
+ .name = "lt8912",
+ .of_match_table = lt8912_of_match,
+ },
+ .id_table = lt8912_i2c_ids,
+ .probe = lt8912_probe,
+ .remove = lt8912_remove,
+};
+
+static int __init lt8912_i2c_drv_init(void)
+{
+ mipi_dsi_driver_register(&lt8912_driver);
+
+ return i2c_add_driver(&lt8912_i2c_driver);
+}
+module_init(lt8912_i2c_drv_init);
+
+static void __exit lt8912_i2c_exit(void)
+{
+ i2c_del_driver(&lt8912_i2c_driver);
+
+ mipi_dsi_driver_unregister(&lt8912_driver);
+}
+module_exit(lt8912_i2c_exit);
+
+MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
+MODULE_DESCRIPTION("Lontium LT8912 MIPI-DSI to LVDS and HDMI/MHL bridge");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/Kconfig b/drivers/gpu/drm/bridge/sn65dsi83/Kconfig
new file mode 100644
index 000000000000..1d8f37f689d3
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/Kconfig
@@ -0,0 +1,7 @@
+config DRM_I2C_SN65DSI83
+ bool "SN65DSI83 mipi dsi to lvds bridge"
+ depends on OF
+ select DRM_MIPI_DSI
+ default y
+ help
+ Support for the sn65dsi83 MIPI DSI to LVDS bridge
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/Makefile b/drivers/gpu/drm/bridge/sn65dsi83/Makefile
new file mode 100644
index 000000000000..dee7f493b323
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/Makefile
@@ -0,0 +1,2 @@
+sn65dsi83-objs := sn65dsi83_drv.o sn65dsi83_brg.o
+obj-$(CONFIG_DRM_I2C_SN65DSI83) := sn65dsi83.o
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c
new file mode 100644
index 000000000000..f4a7713635d6
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2018 CopuLab Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_connector.h>
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include "sn65dsi83_brg.h"
+
+/* Register addresses */
+
+#define SN65DSI83_SOFT_RESET 0x09
+#define SN65DSI83_CORE_PLL 0x0A
+ #define LVDS_CLK_RANGE_SHIFT 1
+ #define HS_CLK_SRC_SHIFT 0
+
+#define SN65DSI83_PLL_DIV 0x0B
+ #define DSI_CLK_DIV_SHIFT 3
+
+#define SN65DSI83_PLL_EN 0x0D
+#define SN65DSI83_DSI_CFG 0x10
+ #define CHA_DSI_LANES_SHIFT 3
+
+#define SN65DSI83_DSI_EQ 0x11
+#define SN65DSI83_CHA_DSI_CLK_RNG 0x12
+#define SN65DSI83_CHB_DSI_CLK_RNG 0x13
+#define SN65DSI83_LVDS_MODE 0x18
+ #define DE_NEG_POLARITY_SHIFT 7
+ #define HS_NEG_POLARITY_SHIFT 6
+ #define VS_NEG_POLARITY_SHIFT 5
+ #define LVDS_LINK_CFG_SHIFT 4
+ #define CHA_24BPP_MODE_SHIFT 3
+ #define CHA_24BPP_FMT1_SHIFT 1
+
+#define SN65DSI83_LVDS_SIGN 0x19
+#define SN65DSI83_LVDS_TERM 0x1A
+#define SN65DSI83_LVDS_CM_ADJ 0x1B
+#define SN65DSI83_CHA_LINE_LEN_LO 0x20
+#define SN65DSI83_CHA_LINE_LEN_HI 0x21
+#define SN65DSI83_CHB_LINE_LEN_LO 0x22
+#define SN65DSI83_CHB_LINE_LEN_HI 0x23
+#define SN65DSI83_CHA_VERT_LINES_LO 0x24
+#define SN65DSI83_CHA_VERT_LINES_HI 0x25
+#define SN65DSI83_CHB_VERT_LINES_LO 0x26
+#define SN65DSI83_CHB_VERT_LINES_HI 0x27
+#define SN65DSI83_CHA_SYNC_DELAY_LO 0x28
+#define SN65DSI83_CHA_SYNC_DELAY_HI 0x29
+#define SN65DSI83_CHB_SYNC_DELAY_LO 0x2A
+#define SN65DSI83_CHB_SYNC_DELAY_HI 0x2B
+#define SN65DSI83_CHA_HSYNC_WIDTH_LO 0x2C
+#define SN65DSI83_CHA_HSYNC_WIDTH_HI 0x2D
+#define SN65DSI83_CHB_HSYNC_WIDTH_LO 0x2E
+#define SN65DSI83_CHB_HSYNC_WIDTH_HI 0x2F
+#define SN65DSI83_CHA_VSYNC_WIDTH_LO 0x30
+#define SN65DSI83_CHA_VSYNC_WIDTH_HI 0x31
+#define SN65DSI83_CHB_VSYNC_WIDTH_LO 0x32
+#define SN65DSI83_CHB_VSYNC_WIDTH_HI 0x33
+#define SN65DSI83_CHA_HORZ_BACKPORCH 0x34
+#define SN65DSI83_CHB_HORZ_BACKPORCH 0x35
+#define SN65DSI83_CHA_VERT_BACKPORCH 0x36
+#define SN65DSI83_CHB_VERT_BACKPORCH 0x37
+#define SN65DSI83_CHA_HORZ_FRONTPORCH 0x38
+#define SN65DSI83_CHB_HORZ_FRONTPORCH 0x39
+#define SN65DSI83_CHA_VERT_FRONTPORCH 0x3A
+#define SN65DSI83_CHB_VERT_FRONTPORCH 0x3B
+#define SN65DSI83_CHA_ERR 0xE5
+#define SN65DSI83_TEST_PATTERN 0x3C
+#define SN65DSI83_REG_3D 0x3D
+#define SN65DSI83_REG_3E 0x3E
+
+static int sn65dsi83_brg_power_on(struct sn65dsi83_brg *brg)
+{
+ dev_info(&brg->client->dev,"%s\n",__func__);
+ gpiod_set_value_cansleep(brg->gpio_enable, 1);
+ /* Wait for 1ms for the internal voltage regulator to stabilize */
+ msleep(1);
+
+ return 0;
+}
+
+static void sn65dsi83_brg_power_off(struct sn65dsi83_brg *brg)
+{
+ dev_info(&brg->client->dev,"%s\n",__func__);
+ gpiod_set_value_cansleep(brg->gpio_enable, 0);
+ /*
+ * The EN pin must be held low for at least 10 ms
+ * before being asserted high
+ */
+ msleep(10);
+}
+
+static int sn65dsi83_write(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+
+ if (ret)
+ dev_err(&client->dev, "failed to write at 0x%02x", reg);
+
+ dev_dbg(&client->dev, "%s: write reg 0x%02x data 0x%02x", __func__, reg, val);
+
+ return ret;
+}
+#define SN65DSI83_WRITE(reg,val) sn65dsi83_write(client, (reg) , (val))
+
+static int sn65dsi83_read(struct i2c_client *client, u8 reg)
+{
+ int ret;
+
+ dev_info(&client->dev, "client 0x%p", client);
+ ret = i2c_smbus_read_byte_data(client, reg);
+
+ if (ret < 0) {
+ dev_err(&client->dev, "failed reading at 0x%02x", reg);
+ return ret;
+ }
+
+ dev_dbg(&client->dev, "%s: read reg 0x%02x data 0x%02x", __func__, reg, ret);
+
+ return ret;
+}
+#define SN65DSI83_READ(reg) sn65dsi83_read(client, (reg))
+
+static int sn65dsi83_brg_start_stream(struct sn65dsi83_brg *brg)
+{
+ int regval;
+ struct i2c_client *client = I2C_CLIENT(brg);
+
+ dev_info(&client->dev,"%s\n",__func__);
+ /* Set the PLL_EN bit (CSR 0x0D.0) */
+ SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x1);
+ /* Wait for the PLL_LOCK bit to be set (CSR 0x0A.7) */
+ msleep(200);
+
+ /* Perform SW reset to apply changes */
+ SN65DSI83_WRITE(SN65DSI83_SOFT_RESET, 0x01);
+
+ /* Read CHA Error register */
+ regval = SN65DSI83_READ(SN65DSI83_CHA_ERR);
+ dev_info(&client->dev, "CHA (0x%02x) = 0x%02x",
+ SN65DSI83_CHA_ERR, regval);
+
+ return 0;
+}
+
+static void sn65dsi83_brg_stop_stream(struct sn65dsi83_brg *brg)
+{
+ struct i2c_client *client = I2C_CLIENT(brg);
+ dev_info(&client->dev,"%s\n",__func__);
+ /* Clear the PLL_EN bit (CSR 0x0D.0) */
+ SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x00);
+}
+
+static int sn65dsi83_calk_clk_range(int min_regval, int max_regval,
+ unsigned long min_clk, unsigned long inc,
+ unsigned long target_clk)
+{
+ int regval = min_regval;
+ unsigned long clk = min_clk;
+
+ while (regval <= max_regval) {
+ if ((clk <= target_clk) && (target_clk < (clk + inc)))
+ return regval;
+
+ regval++;
+ clk += inc;
+ }
+
+ return -1;
+}
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+static int sn65dsi83_calk_div(int min_regval, int max_regval, int min_div,
+ int inc, unsigned long source_clk,
+ unsigned long target_clk)
+{
+ int regval = min_regval;
+ int div = min_div;
+ unsigned long curr_delta;
+ unsigned long prev_delta = ABS(DIV_ROUND_UP(source_clk, div) -
+ target_clk);
+
+ while (regval <= max_regval) {
+ curr_delta = ABS(DIV_ROUND_UP(source_clk, div) - target_clk);
+ if (curr_delta > prev_delta)
+ return --regval;
+
+ regval++;
+ div += inc;
+ }
+
+ return -1;
+}
+
+static int sn65dsi83_brg_configure(struct sn65dsi83_brg *brg)
+{
+ int regval = 0;
+ struct i2c_client *client = I2C_CLIENT(brg);
+ struct videomode *vm = VM(brg);
+
+ u32 dsi_clk = (((PIXCLK * BPP(brg)) / DSI_LANES(brg)) >> 1);
+
+ dev_info(&client->dev, "DSI clock [ %u ] Hz\n",dsi_clk);
+ dev_info(&client->dev, "GeoMetry [ %d x %d ] Hz\n",HACTIVE,VACTIVE);
+
+ /* Reset PLL_EN and SOFT_RESET registers */
+ SN65DSI83_WRITE(SN65DSI83_SOFT_RESET,0x00);
+ SN65DSI83_WRITE(SN65DSI83_PLL_EN,0x00);
+
+ /* LVDS clock setup */
+ if ((25000000 <= PIXCLK) && (PIXCLK < 37500000))
+ regval = 0;
+ else
+ regval = sn65dsi83_calk_clk_range(0x01, 0x05, 37500000, 25000000,
+ PIXCLK);
+
+ if (regval < 0) {
+ dev_err(&client->dev, "failed to configure LVDS clock");
+ return -EINVAL;
+ }
+
+ regval = (regval << LVDS_CLK_RANGE_SHIFT);
+ regval |= (1 << HS_CLK_SRC_SHIFT); /* Use DSI clock */
+ SN65DSI83_WRITE(SN65DSI83_CORE_PLL,regval);
+
+ /* DSI clock range */
+ regval = sn65dsi83_calk_clk_range(0x08, 0x64, 40000000, 5000000, dsi_clk);
+ if (regval < 0) {
+ dev_err(&client->dev, "failed to configure DSI clock range\n");
+ return -EINVAL;
+ }
+ SN65DSI83_WRITE(SN65DSI83_CHA_DSI_CLK_RNG,regval);
+
+ /* DSI clock divider */
+ regval = sn65dsi83_calk_div(0x0, 0x18, 1, 1, dsi_clk, PIXCLK);
+ if (regval < 0) {
+ dev_err(&client->dev, "failed to calculate DSI clock divider");
+ return -EINVAL;
+ }
+
+ regval = regval << DSI_CLK_DIV_SHIFT;
+ SN65DSI83_WRITE(SN65DSI83_PLL_DIV,regval);
+
+ /* Configure DSI_LANES */
+ regval = SN65DSI83_READ(SN65DSI83_DSI_CFG);
+ regval &= ~(3 << CHA_DSI_LANES_SHIFT);
+ regval |= ((4 - DSI_LANES(brg)) << CHA_DSI_LANES_SHIFT);
+ SN65DSI83_WRITE(SN65DSI83_DSI_CFG,regval);
+
+ /* CHA_DSI_DATA_EQ - No Equalization */
+ /* CHA_DSI_CLK_EQ - No Equalization */
+ SN65DSI83_WRITE(SN65DSI83_DSI_EQ,0x00);
+
+ /* Video formats */
+ regval = 0;
+ if (FLAGS & DISPLAY_FLAGS_HSYNC_LOW)
+ regval |= (1 << HS_NEG_POLARITY_SHIFT);
+
+ if (FLAGS & DISPLAY_FLAGS_VSYNC_LOW)
+ regval |= (1 << VS_NEG_POLARITY_SHIFT);
+
+ if (FLAGS & DISPLAY_FLAGS_DE_LOW)
+ regval |= (1 << DE_NEG_POLARITY_SHIFT);
+
+ if (BPP(brg) == 24)
+ regval |= (1 << CHA_24BPP_MODE_SHIFT);
+
+ if (FORMAT(brg) == 1)
+ regval |= (1 << CHA_24BPP_FMT1_SHIFT);
+
+ regval |= (1 << LVDS_LINK_CFG_SHIFT);
+ SN65DSI83_WRITE(SN65DSI83_LVDS_MODE,regval);
+
+ /* Voltage and pins */
+ SN65DSI83_WRITE(SN65DSI83_LVDS_SIGN,0x00);
+ SN65DSI83_WRITE(SN65DSI83_LVDS_TERM,0x03);
+ SN65DSI83_WRITE(SN65DSI83_LVDS_CM_ADJ,0x00);
+
+ /* Configure sync delay to minimal allowed value */
+ SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_LO,0x21);
+ SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_HI,0x00);
+
+ /* Geometry */
+ SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_LO,LOW(HACTIVE));
+ SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_HI,HIGH(HACTIVE));
+
+ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_LO,LOW(VACTIVE));
+ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_HI,HIGH(VACTIVE));
+
+ SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_LO,LOW(HPW));
+ SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_HI,HIGH(HPW));
+
+ SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_LO,LOW(VPW));
+ SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_HI,HIGH(VPW));
+
+ SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_BACKPORCH,LOW(HBP));
+ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_BACKPORCH,LOW(VBP));
+
+ SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_FRONTPORCH,LOW(HFP));
+ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_FRONTPORCH,LOW(VFP));
+
+ SN65DSI83_WRITE(SN65DSI83_TEST_PATTERN,0x00);
+ SN65DSI83_WRITE(SN65DSI83_REG_3D,0x00);
+ SN65DSI83_WRITE(SN65DSI83_REG_3E,0x00);
+
+ /* mute channel B */
+ SN65DSI83_WRITE(SN65DSI83_CHB_DSI_CLK_RNG, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_LO, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_HI, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_LO, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_HI, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_LO, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_HI, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_LO, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_HI, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_LO, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_HI, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_BACKPORCH, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_BACKPORCH, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_FRONTPORCH, 0x00);
+ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_FRONTPORCH, 0x00);
+ return 0;
+}
+
+static int sn65dsi83_brg_setup(struct sn65dsi83_brg *brg)
+{
+ struct i2c_client *client = I2C_CLIENT(brg);
+ dev_info(&client->dev,"%s\n",__func__);
+ sn65dsi83_brg_power_on(brg);
+ return sn65dsi83_brg_configure(brg);
+}
+
+static int sn65dsi83_brg_reset(struct sn65dsi83_brg *brg)
+{
+ /* Soft Reset reg value at power on should be 0x00 */
+ struct i2c_client *client = I2C_CLIENT(brg);
+ int ret = SN65DSI83_READ(SN65DSI83_SOFT_RESET);
+ dev_info(&client->dev,"%s\n",__func__);
+ if (ret != 0x00) {
+ dev_err(&client->dev,"Failed to reset the device");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static struct sn65dsi83_brg_funcs brg_func = {
+ .power_on = sn65dsi83_brg_power_on,
+ .power_off = sn65dsi83_brg_power_off,
+ .setup = sn65dsi83_brg_setup,
+ .reset = sn65dsi83_brg_reset,
+ .start_stream = sn65dsi83_brg_start_stream,
+ .stop_stream = sn65dsi83_brg_stop_stream,
+};
+
+static struct sn65dsi83_brg brg = {
+ .funcs = &brg_func,
+};
+
+struct sn65dsi83_brg *sn65dsi83_brg_get(void) {
+ return &brg;
+}
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h
new file mode 100644
index 000000000000..9f23df8afedc
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h
@@ -0,0 +1,55 @@
+#ifndef _SN65DSI83_BRG_H__
+#define _SN65DSI83_BRG_H__
+
+#include <linux/i2c.h>
+#include <linux/gpio/consumer.h>
+#include <video/videomode.h>
+
+struct sn65dsi83_brg;
+struct sn65dsi83_brg_funcs {
+ int (*power_on)(struct sn65dsi83_brg *sn65dsi8383_brg);
+ void (*power_off)(struct sn65dsi83_brg *sn65dsi8383_brg);
+ int (*reset)(struct sn65dsi83_brg *sn65dsi8383_brg);
+ int (*setup)(struct sn65dsi83_brg *sn65dsi8383_brg);
+ int (*start_stream)(struct sn65dsi83_brg *sn65dsi8383_brg);
+ void (*stop_stream)(struct sn65dsi83_brg *sn65dsi8383_brg);
+};
+
+struct sn65dsi83_brg {
+ struct i2c_client *client;
+ struct gpio_desc *gpio_enable;
+ /* Bridge Panel Parameters */
+ struct videomode vm;
+ u32 width_mm;
+ u32 height_mm;
+ u32 format;
+ u32 bpp;
+
+ u8 num_dsi_lanes;
+ struct sn65dsi83_brg_funcs *funcs;
+};
+struct sn65dsi83_brg *sn65dsi83_brg_get(void);
+
+#define I2C_DEVICE(A) &(A)->client->dev
+#define I2C_CLIENT(A) (A)->client
+#define VM(A) &(A)->vm
+#define BPP(A) (A)->bpp
+#define FORMAT(A) (A)->format
+#define DSI_LANES(A) (A)->num_dsi_lanes
+
+/* The caller has to have a vm structure defined */
+#define PIXCLK vm->pixelclock
+#define HACTIVE vm->hactive
+#define HFP vm->hfront_porch
+#define HBP vm->hback_porch
+#define HPW vm->hsync_len
+#define VACTIVE vm->vactive
+#define VFP vm->vfront_porch
+#define VBP vm->vback_porch
+#define VPW vm->vsync_len
+#define FLAGS vm->flags
+
+#define HIGH(A) (((A) >> 8) & 0xFF)
+#define LOW(A) ((A) & 0xFF)
+
+#endif /* _SN65DSI83_BRG_H__ */
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c
new file mode 100644
index 000000000000..ec7d62cc3275
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c
@@ -0,0 +1,408 @@
+/*
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc_helper.h>
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include "sn65dsi83_timing.h"
+#include "sn65dsi83_brg.h"
+
+struct sn65dsi83 {
+ u8 channel_id;
+ enum drm_connector_status status;
+ bool powered;
+ struct drm_display_mode curr_mode;
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+ struct device_node *host_node;
+ struct mipi_dsi_device *dsi;
+ struct sn65dsi83_brg *brg;
+};
+
+static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83);
+#define DRM_DEVICE(A) A->dev->dev
+/* Connector funcs */
+static struct sn65dsi83 *connector_to_sn65dsi83(struct drm_connector *connector)
+{
+ return container_of(connector, struct sn65dsi83, connector);
+}
+
+static int sn65dsi83_connector_get_modes(struct drm_connector *connector)
+{
+ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
+ struct sn65dsi83_brg *brg = sn65dsi83->brg;
+ struct device *dev = connector->dev->dev;
+ struct drm_display_mode *mode;
+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ u32 *bus_flags = &connector->display_info.bus_flags;
+ int ret;
+
+ dev_info(dev, "%s\n",__func__);
+ mode = drm_mode_create(connector->dev);
+ if (!mode) {
+ DRM_DEV_ERROR(dev, "Failed to create display mode!\n");
+ return 0;
+ }
+
+ drm_display_mode_from_videomode(&brg->vm, mode);
+ mode->width_mm = brg->width_mm;
+ mode->height_mm = brg->height_mm;
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(connector, mode);
+ drm_connector_list_update(connector);
+
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+
+ if (brg->vm.flags & DISPLAY_FLAGS_DE_HIGH)
+ *bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+ if (brg->vm.flags & DISPLAY_FLAGS_DE_LOW)
+ *bus_flags |= DRM_BUS_FLAG_DE_LOW;
+ if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+ if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
+
+ ret = drm_display_info_set_bus_formats(&connector->display_info,
+ &bus_format, 1);
+ if (ret)
+ return ret;
+
+ return 1;
+}
+
+static enum drm_mode_status
+sn65dsi83_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
+ struct device *dev = connector->dev->dev;
+ if (mode->clock > ( sn65dsi83->brg->vm.pixelclock / 1000 ))
+ return MODE_CLOCK_HIGH;
+
+ dev_info(dev, "%s: mode: %d*%d@%d is valid\n",__func__,
+ mode->hdisplay,mode->vdisplay,mode->clock);
+ return MODE_OK;
+}
+
+static struct drm_connector_helper_funcs sn65dsi83_connector_helper_funcs = {
+ .get_modes = sn65dsi83_connector_get_modes,
+ .mode_valid = sn65dsi83_connector_mode_valid,
+};
+
+static enum drm_connector_status
+sn65dsi83_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
+ struct device *dev = connector->dev->dev;
+ enum drm_connector_status status;
+ dev_info(dev, "%s\n",__func__);
+
+ status = connector_status_connected;
+ sn65dsi83->status = status;
+ return status;
+}
+
+int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY);
+
+static struct drm_connector_funcs sn65dsi83_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = sn65dsi83_connector_detect,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+/* Bridge funcs */
+static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct sn65dsi83, bridge);
+}
+
+static void sn65dsi83_bridge_enable(struct drm_bridge *bridge)
+{
+ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
+ dev_info(DRM_DEVICE(bridge),"%s\n",__func__);
+ sn65dsi83->brg->funcs->setup(sn65dsi83->brg);
+ sn65dsi83->brg->funcs->start_stream(sn65dsi83->brg);
+}
+
+static void sn65dsi83_bridge_disable(struct drm_bridge *bridge)
+{
+ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
+ dev_info(DRM_DEVICE(bridge),"%s\n",__func__);
+ sn65dsi83->brg->funcs->stop_stream(sn65dsi83->brg);
+ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
+}
+
+static void sn65dsi83_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adj_mode)
+{
+ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
+ dev_info(DRM_DEVICE(bridge), "%s: mode: %d*%d@%d\n",__func__,
+ mode->hdisplay,mode->vdisplay,mode->clock);
+ drm_mode_copy(&sn65dsi83->curr_mode, adj_mode);
+}
+
+static int sn65dsi83_bridge_attach(struct drm_bridge *bridge)
+{
+ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
+ int ret;
+
+ dev_info(DRM_DEVICE(bridge),"%s\n",__func__);
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found");
+ return -ENODEV;
+ }
+
+ sn65dsi83->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
+
+ ret = drm_connector_init(bridge->dev, &sn65dsi83->connector,
+ &sn65dsi83_connector_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ if (ret) {
+ DRM_ERROR("Failed to initialize connector with drm\n");
+ return ret;
+ }
+ drm_connector_helper_add(&sn65dsi83->connector,
+ &sn65dsi83_connector_helper_funcs);
+ drm_connector_attach_encoder(&sn65dsi83->connector, bridge->encoder);
+
+ ret = sn65dsi83_attach_dsi(sn65dsi83);
+
+ return ret;
+}
+
+static struct drm_bridge_funcs sn65dsi83_bridge_funcs = {
+ .enable = sn65dsi83_bridge_enable,
+ .disable = sn65dsi83_bridge_disable,
+ .mode_set = sn65dsi83_bridge_mode_set,
+ .attach = sn65dsi83_bridge_attach,
+};
+
+static int sn65dsi83_parse_dt(struct device_node *np,
+ struct sn65dsi83 *sn65dsi83)
+{
+ struct device *dev = &sn65dsi83->brg->client->dev;
+ u32 num_lanes = 2, bpp = 24, format = 2, width = 149, height = 93;
+ struct device_node *endpoint;
+
+ endpoint = of_graph_get_next_endpoint(np, NULL);
+ if (!endpoint)
+ return -ENODEV;
+
+ sn65dsi83->host_node = of_graph_get_remote_port_parent(endpoint);
+ if (!sn65dsi83->host_node) {
+ of_node_put(endpoint);
+ return -ENODEV;
+ }
+
+ of_property_read_u32(np, "ti,dsi-lanes", &num_lanes);
+ of_property_read_u32(np, "ti,lvds-format", &format);
+ of_property_read_u32(np, "ti,lvds-bpp", &bpp);
+ of_property_read_u32(np, "ti,width-mm", &width);
+ of_property_read_u32(np, "ti,height-mm", &height);
+
+ if (num_lanes < 1 || num_lanes > 4) {
+ dev_err(dev, "Invalid dsi-lanes: %d\n", num_lanes);
+ return -EINVAL;
+ }
+ sn65dsi83->brg->num_dsi_lanes = num_lanes;
+
+ sn65dsi83->brg->gpio_enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(sn65dsi83->brg->gpio_enable)) {
+ dev_err(dev, "failed to parse enable gpio");
+ return PTR_ERR(sn65dsi83->brg->gpio_enable);
+ }
+
+ sn65dsi83->brg->format = format;
+ sn65dsi83->brg->bpp = bpp;
+
+ sn65dsi83->brg->width_mm = width;
+ sn65dsi83->brg->height_mm = height;
+
+ /* Read default timing if there is not device tree node for */
+ if ((of_get_videomode(np, &sn65dsi83->brg->vm, 0)) < 0)
+ videomode_from_timing(&panel_default_timing, &sn65dsi83->brg->vm);
+
+ of_node_put(endpoint);
+ of_node_put(sn65dsi83->host_node);
+
+ return 0;
+}
+
+static int sn65dsi83_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct sn65dsi83 *sn65dsi83;
+ struct device *dev = &i2c->dev;
+ int ret;
+
+ dev_info(dev,"%s\n",__func__);
+ if (!dev->of_node)
+ return -EINVAL;
+
+ sn65dsi83 = devm_kzalloc(dev, sizeof(*sn65dsi83), GFP_KERNEL);
+ if (!sn65dsi83)
+ return -ENOMEM;
+
+ /* Initialize it before DT parser */
+ sn65dsi83->brg = sn65dsi83_brg_get();
+ sn65dsi83->brg->client = i2c;
+
+ sn65dsi83->powered = false;
+ sn65dsi83->status = connector_status_disconnected;
+
+ i2c_set_clientdata(i2c, sn65dsi83);
+
+ ret = sn65dsi83_parse_dt(dev->of_node, sn65dsi83);
+ if (ret)
+ return ret;
+
+ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
+ sn65dsi83->brg->funcs->power_on(sn65dsi83->brg);
+ ret = sn65dsi83->brg->funcs->reset(sn65dsi83->brg);
+ if (ret != 0x00) {
+ dev_err(dev, "Failed to reset the device");
+ return -ENODEV;
+ }
+ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
+
+
+ sn65dsi83->bridge.funcs = &sn65dsi83_bridge_funcs;
+ sn65dsi83->bridge.of_node = dev->of_node;
+
+ drm_bridge_add(&sn65dsi83->bridge);
+
+ return ret;
+}
+
+static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83)
+{
+ struct device *dev = &sn65dsi83->brg->client->dev;
+ struct mipi_dsi_host *host;
+ struct mipi_dsi_device *dsi;
+ int ret = 0;
+ const struct mipi_dsi_device_info info = { .type = "sn65dsi83",
+ .channel = 0,
+ .node = NULL,
+ };
+
+ dev_info(dev, "%s\n",__func__);
+ host = of_find_mipi_dsi_host_by_node(sn65dsi83->host_node);
+ if (!host) {
+ dev_err(dev, "failed to find dsi host\n");
+ return -EPROBE_DEFER;
+ }
+
+ dsi = mipi_dsi_device_register_full(host, &info);
+ if (IS_ERR(dsi)) {
+ dev_err(dev, "failed to create dsi device\n");
+ ret = PTR_ERR(dsi);
+ return -ENODEV;
+ }
+
+ sn65dsi83->dsi = dsi;
+
+ dsi->lanes = sn65dsi83->brg->num_dsi_lanes;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST;
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach dsi to host\n");
+ mipi_dsi_device_unregister(dsi);
+ }
+
+ return ret;
+}
+
+static void sn65dsi83_detach_dsi(struct sn65dsi83 *sn65dsi83)
+{
+ struct device *dev = &sn65dsi83->brg->client->dev;
+ dev_info(dev, "%s\n",__func__);
+ mipi_dsi_detach(sn65dsi83->dsi);
+ mipi_dsi_device_unregister(sn65dsi83->dsi);
+}
+
+static int sn65dsi83_remove(struct i2c_client *i2c)
+{
+ struct sn65dsi83 *sn65dsi83 = i2c_get_clientdata(i2c);
+ struct device *dev = &sn65dsi83->brg->client->dev;
+ dev_info(dev, "%s\n",__func__);
+
+ sn65dsi83_detach_dsi(sn65dsi83);
+ drm_bridge_remove(&sn65dsi83->bridge);
+
+ return 0;
+}
+
+static const struct i2c_device_id sn65dsi83_i2c_ids[] = {
+ { "sn65dsi83", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, sn65dsi83_i2c_ids);
+
+static const struct of_device_id sn65dsi83_of_ids[] = {
+ { .compatible = "ti,sn65dsi83" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sn65dsi83_of_ids);
+
+static struct mipi_dsi_driver sn65dsi83_dsi_driver = {
+ .driver.name = "sn65dsi83",
+};
+
+static struct i2c_driver sn65dsi83_driver = {
+ .driver = {
+ .name = "sn65dsi83",
+ .of_match_table = sn65dsi83_of_ids,
+ },
+ .id_table = sn65dsi83_i2c_ids,
+ .probe = sn65dsi83_probe,
+ .remove = sn65dsi83_remove,
+};
+
+static int __init sn65dsi83_init(void)
+{
+ if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
+ mipi_dsi_driver_register(&sn65dsi83_dsi_driver);
+
+ return i2c_add_driver(&sn65dsi83_driver);
+}
+module_init(sn65dsi83_init);
+
+static void __exit sn65dsi83_exit(void)
+{
+ i2c_del_driver(&sn65dsi83_driver);
+
+ if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
+ mipi_dsi_driver_unregister(&sn65dsi83_dsi_driver);
+}
+module_exit(sn65dsi83_exit);
+
+MODULE_AUTHOR("CompuLab <compulab@compula.co.il>");
+MODULE_DESCRIPTION("SN65DSI bridge driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h
new file mode 100644
index 000000000000..e9bb6633c376
--- /dev/null
+++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h
@@ -0,0 +1,33 @@
+#ifndef __SN65DSI83_TIMING_H__
+#define __SN65DSI83_TIMING_H__
+
+/* Default Video Parameters */
+#define PIXCLK_INIT 62500000
+
+#define HACTIVE_INIT 1280
+#define HPW_INIT 2
+#define HBP_INIT 6
+#define HFP_INIT 5
+
+#define VACTIVE_INIT 800
+#define VPW_INIT 1
+#define VBP_INIT 2
+#define VFP_INIT 3
+
+static const struct display_timing panel_default_timing = {
+ .pixelclock = { PIXCLK_INIT, PIXCLK_INIT, PIXCLK_INIT },
+ .hactive = { HACTIVE_INIT, HACTIVE_INIT, HACTIVE_INIT },
+ .hfront_porch = { HFP_INIT, HFP_INIT, HFP_INIT },
+ .hsync_len = { HPW_INIT, HPW_INIT, HPW_INIT },
+ .hback_porch = { HBP_INIT, HBP_INIT, HBP_INIT },
+ .vactive = { VACTIVE_INIT, VACTIVE_INIT, VACTIVE_INIT },
+ .vfront_porch = { VFP_INIT, VFP_INIT, VFP_INIT },
+ .vsync_len = { VPW_INIT, VPW_INIT, VPW_INIT },
+ .vback_porch = { VBP_INIT, VBP_INIT, VBP_INIT },
+ .flags = DISPLAY_FLAGS_HSYNC_LOW |
+ DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_LOW |
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+};
+
+#endif /* __SN65DSI83_TIMING_H__ */
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 0c54acd52145..1a29c71228c9 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -212,11 +212,16 @@ imx6dl_hdmi_mode_valid(struct drm_connector *con,
static bool imx8mp_hdmi_check_clk_rate(int rate_khz)
{
- int rate = rate_khz * 1000;
+ int rate;
/* Check hdmi phy pixel clock support rate */
- if (rate != clk_round_rate(imx8mp_clocks[0].clk, rate))
+ rate = clk_round_rate(imx8mp_clocks[0].clk, rate_khz * 1000);
+ /* Drop mode if pixelclk generated is more than 6% off */
+ if ((rate < rate_khz * 940) || (rate > rate_khz * 1060)) {
+ pr_info("%s: mode with pixelclk %i kHz dropped\n",
+ __func__, rate_khz);
return false;
+ }
return true;
}
diff --git a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx.h b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx.h
index 87b5e366b7e6..88049a2e348c 100644
--- a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx.h
+++ b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx.h
@@ -52,6 +52,7 @@ struct imx_mhdp_device {
struct imx_hdp_clks clks;
const struct firmware *fw;
const char *firmware_name;
+ int hdmi_ctrl_gpio;
int bus_type;
diff --git a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx8qm.c b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx8qm.c
index 9bfe5f08f4a3..9c425ac91863 100644
--- a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx8qm.c
+++ b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imx8qm.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <drm/drm_vblank.h>
#include <drm/drm_print.h>
+#include <linux/delay.h>
#include "cdns-mhdp-imx.h"
@@ -571,13 +572,6 @@ int cdns_mhdp_firmware_write_section(struct imx_mhdp_device *imx_mhdp,
return 0;
}
-static void cdns_mhdp_firmware_load_cont(const struct firmware *fw, void *context)
-{
- struct imx_mhdp_device *imx_mhdp = context;
-
- imx_mhdp->fw = fw;
-}
-
static int cdns_mhdp_firmware_load(struct imx_mhdp_device *imx_mhdp)
{
const u8 *iram;
@@ -597,23 +591,25 @@ static int cdns_mhdp_firmware_load(struct imx_mhdp_device *imx_mhdp)
goto out;
if (!imx_mhdp->fw) {
- ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
+ ret = request_firmware_direct(&imx_mhdp->fw,
imx_mhdp->firmware_name,
- imx_mhdp->mhdp.dev, GFP_KERNEL,
- imx_mhdp,
- cdns_mhdp_firmware_load_cont);
+ imx_mhdp->mhdp.dev);
if (ret < 0) {
DRM_ERROR("failed to load firmware\n");
- return -ENOENT;
+ /* Maybe U-Boot loaded the firmware. Therefore, still try to
+ * reset the controller */
+ goto out;
}
- } else {
- iram = imx_mhdp->fw->data + FW_IRAM_OFFSET;
- dram = iram + FW_IRAM_SIZE;
-
- cdns_mhdp_firmware_write_section(imx_mhdp, iram, FW_IRAM_SIZE, ADDR_IMEM);
- cdns_mhdp_firmware_write_section(imx_mhdp, dram, FW_DRAM_SIZE, ADDR_DMEM);
}
+ iram = imx_mhdp->fw->data + FW_IRAM_OFFSET;
+ dram = iram + FW_IRAM_SIZE;
+
+ cdns_mhdp_firmware_write_section(imx_mhdp, iram,
+ FW_IRAM_SIZE, ADDR_IMEM);
+ cdns_mhdp_firmware_write_section(imx_mhdp, dram,
+ FW_DRAM_SIZE, ADDR_DMEM);
+
out:
/* un-reset ucpu */
cdns_mhdp_bus_write(0, &imx_mhdp->mhdp, APB_CTRL);
diff --git a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imxdrv.c b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imxdrv.c
index ead56bed3574..f422516aa354 100644
--- a/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imxdrv.c
+++ b/drivers/gpu/drm/imx/mhdp/cdns-mhdp-imxdrv.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/component.h>
+#include <linux/of_gpio.h>
#include <drm/drm_of.h>
#include <drm/drm_vblank.h>
#include <drm/drm_crtc_helper.h>
@@ -161,6 +162,19 @@ static int cdns_mhdp_imx_bind(struct device *dev, struct device *master,
match = of_match_node(cdns_mhdp_imx_dt_ids, pdev->dev.of_node);
plat_data = match->data;
+
+ imx_mhdp->hdmi_ctrl_gpio = of_get_named_gpio(dev->of_node, "hdmi-ctrl-gpios", 0);
+ if (gpio_is_valid(imx_mhdp->hdmi_ctrl_gpio)) {
+ ret = gpio_request(imx_mhdp->hdmi_ctrl_gpio, "HDMI_CTRL");
+ if (ret < 0) {
+ dev_err(dev, "request HDMI CTRL GPIO failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Set signals depending on HDP device type, 0 DP, 1 HDMI */
+ gpio_direction_output(imx_mhdp->hdmi_ctrl_gpio, !plat_data->is_dp);
+ }
+
encoder = &imx_mhdp->encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
@@ -173,8 +187,10 @@ static int cdns_mhdp_imx_bind(struct device *dev, struct device *master,
* not been registered yet. Defer probing, and hope that
* the required CRTC is added later.
*/
- if (encoder->possible_crtcs == 0)
- return -EPROBE_DEFER;
+ if (encoder->possible_crtcs == 0) {
+ ret = -EPROBE_DEFER;
+ goto err_free_hdmi_gpio;
+ }
drm_encoder_helper_add(encoder, &cdns_mhdp_imx_encoder_helper_funcs);
drm_encoder_init(drm, encoder, &cdns_mhdp_imx_encoder_funcs,
@@ -190,9 +206,16 @@ static int cdns_mhdp_imx_bind(struct device *dev, struct device *master,
* which would have called the encoder cleanup. Do it manually.
*/
if (ret < 0)
- drm_encoder_cleanup(encoder);
+ goto err_cleanup_encoder;
return ret;
+
+err_cleanup_encoder:
+ drm_encoder_cleanup(encoder);
+err_free_hdmi_gpio:
+ if (gpio_is_valid(imx_mhdp->hdmi_ctrl_gpio))
+ gpio_free(imx_mhdp->hdmi_ctrl_gpio);
+ return ret;
}
static void cdns_mhdp_imx_unbind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c b/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c
index 9bd9b2c6b9f5..b58589e4959b 100644
--- a/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c
+++ b/drivers/gpu/drm/imx/sec_mipi_dsim-imx.c
@@ -286,6 +286,7 @@ static int imx_sec_dsim_bind(struct device *dev, struct device *master,
dev);
const struct sec_mipi_dsim_plat_data *pdata;
struct drm_encoder *encoder;
+ static int retry = 0;
dev_dbg(dev, "%s: dsim bind begin\n", __func__);
@@ -329,7 +330,7 @@ static int imx_sec_dsim_bind(struct device *dev, struct device *master,
/* bind sec dsim bridge */
ret = sec_mipi_dsim_bind(dev, master, data, encoder, res, irq, pdata);
if (ret) {
- dev_err(dev, "failed to bind sec dsim bridge: %d\n", ret);
+ dev_err(dev, "failed to bind sec dsim bridge: %d, retry %d\n", ret, retry);
pm_runtime_disable(dev);
drm_encoder_cleanup(encoder);
sec_dsim_of_put_resets(dsim_dev);
@@ -341,7 +342,7 @@ static int imx_sec_dsim_bind(struct device *dev, struct device *master,
* it follows 'one fails, all fail'. It is useful
* when there exists multiple heads display.
*/
- if (ret == -ENODEV)
+ if ((ret == -ENODEV) || ((retry++ >= 3) && (ret == -EPROBE_DEFER)))
return 0;
return ret;
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index fb6664f84721..5e51924a9f5a 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -151,9 +151,9 @@ err:
return -EINVAL;
}
-static u32 get_bus_format_from_bpp(u32 bpp)
+static u32 get_bus_format_from_width(u32 width)
{
- switch (bpp) {
+ switch (width) {
case 16:
return MEDIA_BUS_FMT_RGB565_1X16;
case 18:
@@ -170,7 +170,7 @@ static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb)
struct drm_crtc *crtc = &mxsfb->pipe.crtc;
unsigned int bits_per_pixel = crtc->primary->state->fb->format->depth;
struct drm_device *drm = crtc->dev;
- u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ u32 bus_format = get_bus_format_from_width(mxsfb->bus_width);
int num_bus_formats = mxsfb->connector->display_info.num_bus_formats;
const u32 *bus_formats = mxsfb->connector->display_info.bus_formats;
u32 reg = 0;
@@ -178,7 +178,7 @@ static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb)
/* match the user requested bus_format to one supported by the panel */
if (num_bus_formats) {
- u32 user_bus_format = get_bus_format_from_bpp(bits_per_pixel);
+ u32 user_bus_format = get_bus_format_from_width(bits_per_pixel);
bus_format = bus_formats[0];
for (i = 0; i < num_bus_formats; i++) {
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index aafc29a25a60..735c76299813 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -44,6 +44,9 @@ enum mxsfb_devtype {
MXSFB_V4,
};
+/* default output bus width */
+#define MXSFB_DEFAULT_BUS_WIDTH 24
+
/*
* When adding new formats, make sure to update the num_formats from
* mxsfb_devdata below.
@@ -88,6 +91,25 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
},
};
+/*
+ * There are non-atomic versions of clk_enable()/clk_disable() callbacks
+ * used in IMX8QM/IMX8QXP, so we can't manage axi clk in interrupt handlers
+ */
+#if defined(CONFIG_ARCH_FSL_IMX8QM) || defined(CONFIG_ARCH_FSL_IMX8QXP)
+# define mxsfb_enable_axi_clk(mxsfb) 0
+# define mxsfb_disable_axi_clk(mxsfb)
+#else
+static inline int mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
+{
+ return clk_prepare_enable(mxsfb->clk_axi);
+}
+
+static inline void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb)
+{
+ clk_disable_unprepare(mxsfb->clk_axi);
+}
+#endif
+
static struct mxsfb_drm_private *
drm_pipe_to_mxsfb_drm_private(struct drm_simple_display_pipe *pipe)
{
@@ -232,9 +254,17 @@ static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,
}
pm_runtime_get_sync(drm->dev);
- drm_panel_prepare(mxsfb->panel);
- mxsfb_crtc_enable(mxsfb);
- drm_panel_enable(mxsfb->panel);
+ if (mxsfb->panel) {
+ drm_panel_prepare(mxsfb->panel);
+ mxsfb_crtc_enable(mxsfb);
+ drm_panel_enable(mxsfb->panel);
+ }
+
+ if (mxsfb->bridge) {
+ drm_bridge_pre_enable(mxsfb->bridge);
+ mxsfb_crtc_enable(mxsfb);
+ drm_bridge_enable(mxsfb->bridge);
+ }
}
static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -244,9 +274,18 @@ static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe)
struct drm_crtc *crtc = &pipe->crtc;
struct drm_pending_vblank_event *event;
- drm_panel_disable(mxsfb->panel);
- mxsfb_crtc_disable(mxsfb);
- drm_panel_unprepare(mxsfb->panel);
+ if (mxsfb->bridge) {
+ drm_bridge_disable(mxsfb->bridge);
+ mxsfb_crtc_disable(mxsfb);
+ drm_bridge_post_disable(mxsfb->bridge);
+ }
+
+ if (mxsfb->panel) {
+ drm_panel_disable(mxsfb->panel);
+ mxsfb_crtc_disable(mxsfb);
+ drm_panel_unprepare(mxsfb->panel);
+ }
+
pm_runtime_put_sync(drm->dev);
spin_lock_irq(&drm->event_lock);
@@ -274,14 +313,14 @@ static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
int ret = 0;
- ret = clk_prepare_enable(mxsfb->clk_axi);
+ ret = mxsfb_enable_axi_clk(mxsfb);
if (ret)
return ret;
/* Clear and enable VBLANK IRQ */
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
- clk_disable_unprepare(mxsfb->clk_axi);
+ mxsfb_disable_axi_clk(mxsfb);
return ret;
}
@@ -290,13 +329,13 @@ static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
{
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
- if (clk_prepare_enable(mxsfb->clk_axi))
+ if (mxsfb_enable_axi_clk(mxsfb))
return;
/* Disable and clear VBLANK IRQ */
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
- clk_disable_unprepare(mxsfb->clk_axi);
+ mxsfb_disable_axi_clk(mxsfb);
}
static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
@@ -315,6 +354,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
struct platform_device *pdev = to_platform_device(drm->dev);
struct mxsfb_drm_private *mxsfb;
struct resource *res;
+ u32 bus_width = MXSFB_DEFAULT_BUS_WIDTH;
int ret;
mxsfb = devm_kzalloc(&pdev->dev, sizeof(*mxsfb), GFP_KERNEL);
@@ -349,6 +389,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
return ret;
pm_runtime_enable(drm->dev);
+ pm_runtime_get_sync(drm->dev);
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret < 0) {
@@ -396,6 +437,10 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
}
}
+ /* bus width is needed to set up correct bus format */
+ of_property_read_u32(drm->dev->of_node, "bus-width", &bus_width);
+ mxsfb->bus_width = bus_width;
+
drm->mode_config.min_width = MXSFB_MIN_XRES;
drm->mode_config.min_height = MXSFB_MIN_YRES;
drm->mode_config.max_width = MXSFB_MAX_XRES;
@@ -423,7 +468,8 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
return 0;
err_irq:
- drm_panel_detach(mxsfb->panel);
+ if (mxsfb->panel)
+ drm_panel_detach(mxsfb->panel);
err_vblank:
pm_runtime_disable(drm->dev);
@@ -441,6 +487,7 @@ static void mxsfb_unload(struct drm_device *drm)
drm->dev_private = NULL;
+ pm_runtime_put_sync(drm->dev);
pm_runtime_disable(drm->dev);
}
@@ -457,7 +504,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
struct mxsfb_drm_private *mxsfb = drm->dev_private;
u32 reg;
- clk_prepare_enable(mxsfb->clk_axi);
+ mxsfb_enable_axi_clk(mxsfb);
reg = readl(mxsfb->base + LCDC_CTRL1);
@@ -466,7 +513,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
- clk_disable_unprepare(mxsfb->clk_axi);
+ mxsfb_disable_axi_clk(mxsfb);
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 54c06445be96..dffe4b8f52f7 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -34,6 +34,7 @@ struct mxsfb_drm_private {
struct drm_bridge *bridge;
u32 max_bw;
+ u32 bus_width;
};
int mxsfb_setup_crtc(struct drm_device *dev);
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index bf5fcc3e5379..7e7655e002c4 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -23,6 +23,11 @@
#include <drm/drm_crtc.h>
#include <drm/drm_panel.h>
+enum panel_type {
+ PANEL_LVDS,
+ PANEL_DPI
+};
+
struct panel_lvds {
struct drm_panel panel;
struct device *dev;
@@ -124,7 +129,9 @@ static int panel_lvds_get_modes(struct drm_panel *panel)
connector->display_info.height_mm = lvds->height;
drm_display_info_set_bus_formats(&connector->display_info,
&lvds->bus_format, 1);
- connector->display_info.bus_flags = lvds->data_mirror
+ drm_bus_flags_from_videomode(&lvds->video_mode,
+ &connector->display_info.bus_flags);
+ connector->display_info.bus_flags |= lvds->data_mirror
? DRM_BUS_FLAG_DATA_LSB_TO_MSB
: DRM_BUS_FLAG_DATA_MSB_TO_LSB;
@@ -145,6 +152,7 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
struct display_timing timing;
const char *mapping;
int ret;
+ enum panel_type type;
ret = of_get_display_timing(np, "panel-timing", &timing);
if (ret < 0) {
@@ -177,13 +185,30 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
return -ENODEV;
}
- if (!strcmp(mapping, "jeida-18")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
- } else if (!strcmp(mapping, "jeida-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
- } else if (!strcmp(mapping, "vesa-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
- } else {
+ type = (enum panel_type)of_device_get_match_data(lvds->dev);
+ switch (type) {
+ case PANEL_LVDS:
+ if (!strcmp(mapping, "jeida-18")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
+ } else if (!strcmp(mapping, "jeida-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
+ } else if (!strcmp(mapping, "vesa-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
+ }
+ break;
+ case PANEL_DPI:
+ if (!strcmp(mapping, "rgb24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ } else if (!strcmp(mapping, "rgb565")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
+ } else if (!strcmp(mapping, "bgr666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
+ } else if (!strcmp(mapping, "lvds666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
+ }
+ };
+
+ if (!lvds->bus_format) {
dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
np, "data-mapping");
return -EINVAL;
@@ -278,7 +303,8 @@ static int panel_lvds_remove(struct platform_device *pdev)
}
static const struct of_device_id panel_lvds_of_table[] = {
- { .compatible = "panel-lvds", },
+ { .compatible = "panel-lvds", .data = (void *)PANEL_LVDS },
+ { .compatible = "panel-dpi", .data = (void *)PANEL_DPI },
{ /* Sentinel */ },
};
@@ -288,7 +314,7 @@ static struct platform_driver panel_lvds_driver = {
.probe = panel_lvds_probe,
.remove = panel_lvds_remove,
.driver = {
- .name = "panel-lvds",
+ .name = "panel-generic",
.of_match_table = panel_lvds_of_table,
},
};
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 2a5214d2eb80..147e1fea4a5a 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2070,6 +2070,85 @@ static const struct panel_desc lg_lp129qe = {
},
};
+static const struct drm_display_mode lg_lp156wf1_mode = {
+ .clock = 138500,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 48,
+ .hsync_end = 1920 + 48 + 32,
+ .htotal = 1920 + 48 + 32 + 80,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 3,
+ .vsync_end = 1080 + 3 + 5,
+ .vtotal = 1080 + 3 + 5 + 23,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc lg_lp156wf1 = {
+ .modes = &lg_lp156wf1_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 345,
+ .height = 194,
+ },
+};
+
+static const struct display_timing logictechno_lt161010_2nh_timing = {
+ .pixelclock = { 26400000, 33300000, 46800000 },
+ .hactive = { 800, 800, 800 },
+ .hfront_porch = { 16, 210, 354 },
+ .hback_porch = { 46, 46, 46 },
+ .hsync_len = { 1, 20, 40 },
+ .vactive = { 480, 480, 480 },
+ .vfront_porch = { 7, 22, 147 },
+ .vback_porch = { 23, 23, 23 },
+ .vsync_len = { 1, 10, 20 },
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
+ DISPLAY_FLAGS_SYNC_POSEDGE,
+};
+
+static const struct panel_desc logictechno_lt161010_2nh = {
+ .timings = &logictechno_lt161010_2nh_timing,
+ .num_timings = 1,
+ .size = {
+ .width = 154,
+ .height = 86,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH |
+ DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
+ DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
+};
+
+static const struct display_timing logictechno_lt170410_2whc_timing = {
+ .pixelclock = { 68900000, 71100000, 73400000 },
+ .hactive = { 1280, 1280, 1280 },
+ .hfront_porch = { 23, 60, 71 },
+ .hback_porch = { 23, 60, 71 },
+ .hsync_len = { 15, 40, 47 },
+ .vactive = { 800, 800, 800 },
+ .vfront_porch = { 5, 7, 10 },
+ .vback_porch = { 5, 7, 10 },
+ .vsync_len = { 6, 9, 12 },
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
+ DISPLAY_FLAGS_SYNC_POSEDGE,
+};
+
+static const struct panel_desc logictechno_lt170410_2whc = {
+ .timings = &logictechno_lt170410_2whc_timing,
+ .num_timings = 1,
+ .size = {
+ .width = 217,
+ .height = 136,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH |
+ DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
+ DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
+};
+
static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
.clock = 30400,
.hdisplay = 800,
@@ -3338,9 +3417,21 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "lg,lp129qe",
.data = &lg_lp129qe,
}, {
+ .compatible = "lg,lp156wf1",
+ .data = &lg_lp156wf1,
+ }, {
.compatible = "logicpd,type28",
.data = &logicpd_type_28,
}, {
+ .compatible = "logictechno,lt161010-2nhc",
+ .data = &logictechno_lt161010_2nh,
+ }, {
+ .compatible = "logictechno,lt161010-2nhr",
+ .data = &logictechno_lt161010_2nh,
+ }, {
+ .compatible = "logictechno,lt170410-2whc",
+ .data = &logictechno_lt170410_2whc,
+ }, {
.compatible = "mitsubishi,aa070mc01-ca1",
.data = &mitsubishi_aa070mc01,
}, {
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 5e6392294c03..5bf10f3258d8 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -49,6 +49,7 @@ enum lm75_type { /* keep sorted in alphabetical order */
tmp75,
tmp75b,
tmp75c,
+ tmp1075,
};
/**
@@ -291,6 +292,13 @@ static const struct lm75_params device_params[] = {
.clr_mask = 1 << 5, /*not one-shot mode*/
.default_resolution = 12,
.default_sample_time = MSEC_PER_SEC / 12,
+ },
+ [tmp1075] = { /* not one-shot mode, 27.5 ms sample rate */
+ .clr_mask = 1 << 5 | 1 << 6 | 1 << 7,
+ .default_resolution = 12,
+ .default_sample_time = 28,
+ .num_sample_times = 4,
+ .sample_times = (unsigned int []){ 28, 55, 110, 220 },
}
};
@@ -637,6 +645,7 @@ static const struct i2c_device_id lm75_ids[] = {
{ "tmp75", tmp75, },
{ "tmp75b", tmp75b, },
{ "tmp75c", tmp75c, },
+ { "tmp1075", tmp1075, },
{ /* LIST END */ }
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);
@@ -746,6 +755,10 @@ static const struct of_device_id __maybe_unused lm75_of_match[] = {
.compatible = "ti,tmp75c",
.data = (void *)tmp75c
},
+ {
+ .compatible = "ti,tmp1075",
+ .data = (void *)tmp1075
+ },
{ },
};
MODULE_DEVICE_TABLE(of, lm75_of_match);
diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c
index 7364764baaeb..b1065c9cb292 100644
--- a/drivers/hwmon/sht3x.c
+++ b/drivers/hwmon/sht3x.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/platform_data/sht3x.h>
+#include <linux/of.h>
/* commands (high precision mode) */
static const unsigned char sht3x_cmd_measure_blocking_hpm[] = { 0x2c, 0x06 };
@@ -671,6 +672,7 @@ static int sht3x_probe(struct i2c_client *client,
struct i2c_adapter *adap = client->adapter;
struct device *dev = &client->dev;
const struct attribute_group **attribute_groups;
+ struct device_node *np = client->dev.of_node;
/*
* we require full i2c support since the sht3x uses multi-byte read and
@@ -696,8 +698,16 @@ static int sht3x_probe(struct i2c_client *client,
data->client = client;
crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL);
- if (client->dev.platform_data)
- data->setup = *(struct sht3x_platform_data *)dev->platform_data;
+ if (np) {
+ if (of_property_read_bool(np, "sensirion,blocking-io"))
+ data->setup.blocking_io = true;
+ if (of_property_read_bool(np, "sensirion,no-high-precision"))
+ data->setup.high_precision = false;
+ } else {
+ if (client->dev.platform_data)
+ data->setup = *(struct sht3x_platform_data *)
+ dev->platform_data;
+ }
sht3x_select_command(data);
@@ -740,8 +750,20 @@ static const struct i2c_device_id sht3x_ids[] = {
MODULE_DEVICE_TABLE(i2c, sht3x_ids);
+#ifdef CONFIG_OF
+static const struct of_device_id sht3x_dt_match[] = {
+ { .compatible = "sensirion,sht3x" },
+ { .compatible = "sensirion,sts3x" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sht3x_dt_match);
+#endif
+
static struct i2c_driver sht3x_i2c_driver = {
- .driver.name = "sht3x",
+ .driver = {
+ .name = "sht3x",
+ .of_match_table = of_match_ptr(sht3x_dt_match),
+ },
.probe = sht3x_probe,
.id_table = sht3x_ids,
};
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 0d59b0752bae..d59edf96aa65 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -58,6 +59,7 @@
/* Default value */
#define IMX_I2C_BIT_RATE 100000 /* 100kHz */
#define IMX_I2C_MAX_E_BIT_RATE 384000 /* 384kHz from e7805 errata*/
+#define IMX_I2C_MAX_RETRIES 3 /* Retries on arbitration loss */
/*
* Enable DMA if transfer byte size is bigger than this threshold.
@@ -518,7 +520,7 @@ static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits)
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
}
-static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool atomic)
{
unsigned long orig_jiffies = jiffies;
unsigned int temp;
@@ -547,15 +549,38 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
"<%s> I2C bus is busy\n", __func__);
return -ETIMEDOUT;
}
- schedule();
+ if (atomic)
+ udelay(100);
+ else
+ schedule();
+
}
return 0;
}
-static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx, bool atomic)
{
- wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+ if (atomic) {
+ void __iomem *addr = i2c_imx->base + (IMX_I2C_I2SR << i2c_imx->hwdata->regshift);
+ unsigned int regval;
+
+ /*
+ * The formula for the poll timeout is documented in the RM
+ * Rev.5 on page 1878:
+ * T_min = 10/F_scl
+ * Set the value hard as it is done for the non-atomic use-case.
+ * Use 10 kHz for the calculation since this is the minimum
+ * allowed SMBus frequency. Also add an offset of 100us since it
+ * turned out that the I2SR_IIF bit isn't set correctly within
+ * the minimum timeout in polling mode.
+ */
+ readb_poll_timeout_atomic(addr, regval, regval & I2SR_IIF, 5, 1000 + 100);
+ i2c_imx->i2csr = regval;
+ imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
+ } else {
+ wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+ }
if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
@@ -654,7 +679,7 @@ static int i2c_imx_clk_notifier_call(struct notifier_block *nb,
return notifier_from_errno(ret);
}
-static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic)
{
unsigned int temp = 0;
int result;
@@ -671,23 +696,29 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode, i2c_imx, IMX_I2C_I2CR);
/* Wait controller to be stable */
- usleep_range(50, 150);
+ if (atomic)
+ udelay(50);
+ else
+ usleep_range(50, 150);
/* Start I2C transaction */
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp |= I2CR_MSTA;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
+ result = i2c_imx_bus_busy(i2c_imx, 1, atomic);
if (result)
return result;
temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+ if (atomic)
+ temp &= ~I2CR_IIEN; /* Disable interrupt */
+
temp &= ~I2CR_DMAEN;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
return result;
}
-static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
+static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
{
unsigned int temp = 0;
@@ -711,7 +742,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
}
if (!i2c_imx->stopped)
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, atomic);
/* Disable I2C controller */
temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
@@ -786,7 +817,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
/* The last data byte must be transferred by the CPU. */
imx_i2c_write_reg(msgs->buf[msgs->len-1],
i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, false);
if (result)
return result;
@@ -845,7 +876,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
msgs->buf[msgs->len-2] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
/* read n byte data */
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, false);
if (result)
return result;
@@ -861,7 +892,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
if (!i2c_imx->stopped)
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, false);
} else {
/*
* For i2c master receiver repeat restart operation like:
@@ -879,7 +910,8 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
return 0;
}
-static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
+ bool atomic)
{
int i, result;
@@ -888,7 +920,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
/* write slave address */
imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -902,7 +934,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
"<%s> write byte: B%d=0x%X\n",
__func__, i, msgs->buf[i]);
imx_i2c_write_reg(msgs->buf[i], i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -912,7 +944,8 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
return 0;
}
-static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg)
+static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
+ bool is_lastmsg, bool atomic)
{
int i, result;
unsigned int temp;
@@ -925,7 +958,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
/* write slave address */
imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -958,7 +991,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
for (i = 0; i < msgs->len; i++) {
u8 len = 0;
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
/*
@@ -989,7 +1022,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
if (!i2c_imx->stopped)
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, atomic);
} else {
/*
* For i2c master receiver repeat restart operation like:
@@ -1093,8 +1126,8 @@ static int i2c_imx_recovery_for_layerscape(struct imx_i2c_struct *i2c_imx)
return 0;
}
-static int i2c_imx_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs, int num)
+static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num, bool atomic)
{
unsigned int i, temp;
int result;
@@ -1116,15 +1149,11 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
enable_runtime_pm = true;
}
- result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
- if (result < 0)
- goto out;
-
/*
* workround for ERR010027: ensure that the I2C BUS is idle
* before switching to master mode and attempting a Start cycle
*/
- result = i2c_imx_bus_busy(i2c_imx, 0);
+ result = i2c_imx_bus_busy(i2c_imx, 0, atomic);
if (result) {
/* timeout */
if ((result == -ETIMEDOUT) && (i2c_imx->layerscape_bus_recover == 1))
@@ -1134,11 +1163,15 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
}
/* Start I2C transfer */
- result = i2c_imx_start(i2c_imx);
+ result = i2c_imx_start(i2c_imx, atomic);
if (result) {
- if (i2c_imx->adapter.bus_recovery_info) {
+ /*
+ * Bus recovery uses gpiod_get_value_cansleep() which is not
+ * allowed within atomic context.
+ */
+ if (!atomic && i2c_imx->adapter.bus_recovery_info) {
i2c_recover_bus(&i2c_imx->adapter);
- result = i2c_imx_start(i2c_imx);
+ result = i2c_imx_start(i2c_imx, atomic);
}
}
@@ -1156,7 +1189,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp |= I2CR_RSTA;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
+ result = i2c_imx_bus_busy(i2c_imx, 1, atomic);
if (result)
goto fail0;
}
@@ -1180,13 +1213,14 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
(temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
(temp & I2SR_RXAK ? 1 : 0));
#endif
- if (msgs[i].flags & I2C_M_RD)
- result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);
- else {
- if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
+ if (msgs[i].flags & I2C_M_RD) {
+ result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
+ } else {
+ if (!atomic &&
+ i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
else
- result = i2c_imx_write(i2c_imx, &msgs[i]);
+ result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
}
if (result)
goto fail0;
@@ -1194,10 +1228,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
fail0:
/* Stop I2C transfer */
- i2c_imx_stop(i2c_imx);
-
- pm_runtime_mark_last_busy(i2c_imx->adapter.dev.parent);
- pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent);
+ i2c_imx_stop(i2c_imx, atomic);
out:
if (enable_runtime_pm)
@@ -1209,6 +1240,41 @@ out:
return (result < 0) ? result : num;
}
+static int i2c_imx_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
+ int result;
+
+ result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
+ if (result < 0)
+ return result;
+
+ result = i2c_imx_xfer_common(adapter, msgs, num, false);
+
+ pm_runtime_mark_last_busy(i2c_imx->adapter.dev.parent);
+ pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent);
+
+ return result;
+}
+
+static int i2c_imx_xfer_atomic(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
+ int result;
+
+ result = clk_enable(i2c_imx->clk);
+ if (result)
+ return result;
+
+ result = i2c_imx_xfer_common(adapter, msgs, num, true);
+
+ clk_disable(i2c_imx->clk);
+
+ return result;
+}
+
static void i2c_imx_prepare_recovery(struct i2c_adapter *adap)
{
struct imx_i2c_struct *i2c_imx;
@@ -1457,8 +1523,9 @@ static int i2c_imx_unreg_slave(struct i2c_client *client)
#endif
static const struct i2c_algorithm i2c_imx_algo = {
- .master_xfer = i2c_imx_xfer,
- .functionality = i2c_imx_func,
+ .master_xfer = i2c_imx_xfer,
+ .master_xfer_atomic = i2c_imx_xfer_atomic,
+ .functionality = i2c_imx_func,
#if IS_ENABLED(CONFIG_I2C_SLAVE)
.reg_slave = i2c_imx_reg_slave,
.unreg_slave = i2c_imx_unreg_slave,
@@ -1526,6 +1593,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx->adapter.dev.parent = &pdev->dev;
i2c_imx->adapter.nr = pdev->id;
i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
+ i2c_imx->adapter.retries = IMX_I2C_MAX_RETRIES;
i2c_imx->base = base;
ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 7823dfaa013a..7420f73a509a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -120,6 +120,16 @@ config TOUCHSCREEN_ADC
To compile this driver as a module, choose M here: the
module will be called resistive-adc-touch.ko.
+config TOUCHSCREEN_AR1020_I2C
+ tristate "Microchip AR1020 I2C touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have a Microchip AR1020 I2C Controller and
+ want to enable support for the built-in touchscreen.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ar1020-i2c.
+
config TOUCHSCREEN_AR1021_I2C
tristate "Microchip AR1020/1021 i2c touchscreen"
depends on I2C && OF
@@ -747,6 +757,13 @@ config TOUCHSCREEN_MIGOR
To compile this driver as a module, choose M here: the
module will be called migor_ts.
+config TOUCHSCREEN_FUSION_F0710A
+ tristate "TouchRevolution Fusion F0710A Touchscreens"
+ depends on I2C
+ help
+ Say Y here if you want to support the multi-touch input driver for
+ the TouchRevolution Fusion 7 and 10 panels.
+
config TOUCHSCREEN_TOUCHRIGHT
tristate "Touchright serial touchscreen"
select SERIO
@@ -1308,11 +1325,11 @@ config TOUCHSCREEN_ZFORCE
config TOUCHSCREEN_COLIBRI_VF50
tristate "Toradex Colibri on board touchscreen driver"
- depends on IIO && VF610_ADC
+ depends on IIO
depends on GPIOLIB || COMPILE_TEST
help
- Say Y here if you have a Colibri VF50 and plan to use
- the on-board provided 4-wire touchscreen driver.
+ Say Y here if you have a Apalis iMX8 or Colibri VF50 and plan
+ to use the on-board provided 4-wire touchscreen controller.
If unsure, say N.
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 28985ca20b7e..e98ea5886300 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
obj-$(CONFIG_TOUCHSCREEN_ADC) += resistive-adc-touch.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
+obj-$(CONFIG_TOUCHSCREEN_AR1020_I2C) += ar1020-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
@@ -45,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
+obj-$(CONFIG_TOUCHSCREEN_FUSION_F0710A) += fusion_F0710A.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX) += synaptics_dsx/
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
diff --git a/drivers/input/touchscreen/ar1020-i2c.c b/drivers/input/touchscreen/ar1020-i2c.c
new file mode 100644
index 000000000000..1ecfbecf460d
--- /dev/null
+++ b/drivers/input/touchscreen/ar1020-i2c.c
@@ -0,0 +1,500 @@
+/*
+ * Microchip I2C Touchscreen Driver
+ *
+ * Copyright (c) 2011 Microchip Technology, Inc.
+ *
+ * http://www.microchip.com/mtouch
+ */
+
+/*
+ * 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/input.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+/* The private data structure that is referenced within the I2C bus driver */
+struct ar1020_i2c_priv {
+ struct i2c_client *client;
+ struct input_dev *input;
+ int irq;
+ int testCount;
+ int command_pending;
+ int use_count;
+ int button;
+ struct delayed_work reenable_work;
+};
+
+/*
+ * These are all the sysfs variables used to store and retrieve information
+ * from a user-level application
+ */
+static char sendBuffer[100];
+static char receiveBuffer[100];
+static int commandDataPending;
+
+/*
+ * These variables allows the IRQ to be specified via a module parameter
+ * or kernel parameter. To configuration of these value, please see
+ * driver documentation.
+ */
+static int touchIRQ;
+
+module_param(touchIRQ, int, S_IRUGO);
+
+
+/*
+ * Since the reference to private data is stored within the I2C
+ * bus driver, we will store another reference within this driver
+ * so the sysfs related function may also access this data
+ */
+struct ar1020_i2c_priv *g_priv;
+
+/*
+ * Display value of "commandDataPending" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t commandDataPending_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", commandDataPending);
+}
+
+/*
+ * Save value to "commandDataPending" variable from application that is
+ * requesting this.
+ */
+static ssize_t commandDataPending_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ sscanf(buf, "%d", &commandDataPending);
+ return count;
+}
+
+static struct kobj_attribute commandDataPending_attribute =
+ __ATTR(commandDataPending, 0666, commandDataPending_show,
+ commandDataPending_store);
+
+
+/*
+ * Display value of "receiveBuffer" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t receiveBuffer_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ /* receive data is no longer pending */
+ commandDataPending = 0;
+ return sprintf(buf, "%s", receiveBuffer);
+}
+
+/*
+ * Save value to "receiveBuffer" variable from application that is
+ * requesting this.
+ */
+static ssize_t receiveBuffer_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ return snprintf(receiveBuffer, sizeof(receiveBuffer), "%s", buf);
+}
+
+static struct kobj_attribute receiveBuffer_attribute =
+ __ATTR(receiveBuffer, 0666, receiveBuffer_show, receiveBuffer_store);
+
+/*
+ * Display value of "sendBuffer" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t sendBuffer_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s", sendBuffer);
+}
+
+/*
+ * Save value to "sendBuffer" variable from application that is
+ * requesting this.
+ */
+static ssize_t sendBuffer_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int data[8];
+ char buff[8];
+ int cnt;
+ int i;
+ struct ar1020_i2c_priv *priv = g_priv;
+
+ commandDataPending = 0;
+
+ cnt = sscanf(buf, "%x %x %x %x %x %x %x %x", &data[0], &data[1],
+ &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]);
+
+ pr_debug("AR1020 I2C: Processed %d bytes.\n", cnt);
+
+ /* Verify command string to send to controller is valid */
+ if (cnt < 3)
+ pr_info("AR1020 I2C: Insufficient command bytes to process.\n");
+ else if (data[0] != 0x0)
+ pr_info("AR1020 I2C: Leading zero required when sending I2C commands.\n");
+ else if (data[1] != 0x55)
+ pr_info("AR1020 I2C: Invalid header byte (0x55 expected).\n");
+ else if (data[2] != (cnt - 3))
+ pr_info("AR1020 I2C: Number of command bytes specified not "
+ "valid for current string.\n");
+
+ strcpy(sendBuffer, "");
+ pr_debug("AR1020 I2C: sending command bytes: ");
+ for (i = 0; i < cnt; i++) {
+ buff[i] = (char)data[i];
+ pr_debug("0x%02x ", data[i]);
+ }
+ pr_debug("\n");
+
+ if (priv) {
+ priv->command_pending = 1;
+ i2c_master_send(priv->client, buff, cnt);
+ }
+
+ return snprintf(sendBuffer, sizeof(sendBuffer), "%s", buf);
+}
+
+static struct kobj_attribute sendBuffer_attribute =
+ __ATTR(sendBuffer, 0666, sendBuffer_show, sendBuffer_store);
+
+/*
+ * Create a group of calibration attributes so we may work with them
+ * as a set.
+ */
+static struct attribute *attrs[] = {
+ &commandDataPending_attribute.attr,
+ &receiveBuffer_attribute.attr,
+ &sendBuffer_attribute.attr,
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = attrs,
+};
+
+static struct kobject *ar1020_kobj;
+
+static void irq_reenable_work(struct work_struct *work)
+{
+ struct ar1020_i2c_priv *priv = container_of(work,
+ struct ar1020_i2c_priv, reenable_work.work);
+
+ enable_irq(priv->irq);
+}
+
+/*
+ * When the controller interrupt is asserted, this function is scheduled
+ * to be called to read the controller data.
+ */
+static irqreturn_t touch_irq_handler_func(int irq, void *dev_id)
+{
+ struct ar1020_i2c_priv *priv = (struct ar1020_i2c_priv *)dev_id;
+ int i;
+ int cnt;
+ unsigned char packet[9];
+ int x;
+ int y;
+ int button;
+
+ for (i = 0; i < 5; i++)
+ packet[i] = 0;
+
+ /*
+ * We want to ensure we only read packets when we are not in the middle
+ * of command communication. Disable command mode after receiving
+ * command response to resume receiving packets.
+ */
+ cnt = i2c_master_recv(priv->client, packet,
+ (priv->command_pending) ? 9 : 5);
+
+ if (cnt <= 0)
+ goto error;
+
+ if (packet[0] == 0x55) {
+ unsigned char *p = receiveBuffer;
+ unsigned char *pend = p + sizeof(receiveBuffer) - 2;
+ /* process up to 9 bytes */
+ strcpy(receiveBuffer, "");
+
+ priv->command_pending = 0;
+
+ if (packet[1] > 6)
+ pr_info("AR1020 I2C: invalid byte count\n");
+ else if (cnt > packet[1] + 2)
+ cnt = packet[1] + 2;
+
+ for (i = 0; i < cnt; i++) {
+ int ret = snprintf(p, pend - p, " 0x%02x", packet[i]);
+ if (ret <= 0)
+ break;
+ p += ret;
+ if (p >= pend)
+ break;
+ }
+ *p++ = '\n';
+ *p++ = 0;
+ pr_info("AR1020 I2C: command response: %s", receiveBuffer);
+ commandDataPending = 1;
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Decode packets of data from a device path using AR1XXX protocol.
+ * Data format, 5 bytes: SYNC, DATA1, DATA2, DATA3, DATA4
+ * SYNC [7:0]: 1,0,0,0,0,TOUCHSTATUS[0:0]
+ * DATA1[7:0]: 0,X-LOW[6:0]
+ * DATA2[7:0]: 0,X-HIGH[4:0]
+ * DATA3[7:0]: 0,Y-LOW[6:0]
+ * DATA4[7:0]: 0,Y-HIGH[4:0]
+ *
+ * TOUCHSTATUS: 0 = Touch up, 1 = Touch down
+ */
+ if ((packet[0] & 0xfe) != 0x80) {
+ pr_err("AR1020 I2C: 1st Touch byte not valid. Value: 0x%02x\n",
+ packet[0]);
+ goto error; /* irq line may be shorted high, let's delay */
+ }
+ for (i = 1; i < 5; i++) {
+ /* verify byte is valid for current index */
+ if (0x80 & packet[i]) {
+ pr_err("AR1020 I2C: Touch byte not valid. Value: "
+ "0x%02x Index: 0x%02x\n", packet[i], i);
+ goto error;
+ }
+ }
+ x = ((packet[2] & 0x1f) << 7) | (packet[1] & 0x7f);
+ y = ((packet[4] & 0x1f) << 7) | (packet[3] & 0x7f);
+ button = (packet[0] & 1);
+
+ if (!button && !priv->button)
+ return IRQ_HANDLED;
+
+ priv->button = button;
+ input_report_abs(priv->input, ABS_X, x);
+ input_report_abs(priv->input, ABS_Y, y);
+ input_report_key(priv->input, BTN_TOUCH, button);
+ input_sync(priv->input);
+ return IRQ_HANDLED;
+error:
+ disable_irq_nosync(priv->irq);
+ schedule_delayed_work(&priv->reenable_work, 100);
+ return IRQ_HANDLED;
+}
+
+static int ar1020_i2c_open(struct input_dev *idev)
+{
+ struct ar1020_i2c_priv *priv = input_get_drvdata(idev);
+
+ if (priv->use_count++ == 0)
+ enable_irq(priv->irq);
+ return 0;
+}
+
+static void ar1020_i2c_close(struct input_dev *idev)
+{
+ struct ar1020_i2c_priv *priv = input_get_drvdata(idev);
+
+ if (--priv->use_count == 0)
+ disable_irq(priv->irq);
+}
+
+/*
+ * After the kernel's platform specific source files have been modified to
+ * reference the "ar1020_i2c" driver, this function will then be called.
+ * This function needs to be called to finish registering the driver.
+ */
+static int ar1020_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ar1020_i2c_priv *priv = NULL;
+ struct input_dev *input_dev = NULL;
+ int err = 0;
+ int irq;
+
+ pr_info("%s: begin\n", __func__);
+
+ if (!client) {
+ pr_err("AR1020 I2C: client pointer is NULL\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ irq = client->irq;
+ if (touchIRQ)
+ irq = touchIRQ;
+
+ if (!irq) {
+ pr_err("AR1020 I2C: no IRQ set for touch controller\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ priv = kzalloc(sizeof(struct ar1020_i2c_priv), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!priv) {
+ pr_err("AR1020 I2C: kzalloc error\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ if (!input_dev) {
+ pr_err("AR1020 I2C: input allocate error\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ priv->client = client;
+ priv->irq = irq;
+ priv->input = input_dev;
+ INIT_DELAYED_WORK(&priv->reenable_work, irq_reenable_work);
+
+ input_dev->name = "AR1020 Touchscreen";
+ input_dev->id.bustype = BUS_I2C;
+
+ input_dev->open = ar1020_i2c_open;
+ input_dev->close = ar1020_i2c_close;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+ input_set_abs_params(input_dev, ABS_X, 0, 4095, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 4095, 0, 0);
+ input_set_drvdata(input_dev, priv);
+ err = input_register_device(input_dev);
+ if (err) {
+ pr_err("AR1020 I2C: error registering input device\n");
+ goto error;
+ }
+
+ /* set type and register gpio pin as our interrupt */
+ err = request_threaded_irq(priv->irq, NULL, touch_irq_handler_func,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "AR1020 I2C IRQ",
+ priv);
+ if (err < 0)
+ goto error1;
+ disable_irq(priv->irq); /* wait for open */
+ i2c_set_clientdata(client, priv);
+ /*
+ * save pointer so sysfs helper functions may also have access
+ * to private data
+ */
+ g_priv = priv;
+ return 0;
+
+error1:
+ input_unregister_device(input_dev);
+error:
+ if (input_dev)
+ input_free_device(input_dev);
+
+ kfree(priv);
+ return err;
+
+}
+
+/*
+ * Unregister/remove the kernel driver from memory.
+ */
+static int ar1020_i2c_remove(struct i2c_client *client)
+{
+ struct ar1020_i2c_priv *priv =
+ (struct ar1020_i2c_priv *)i2c_get_clientdata(client);
+
+ free_irq(priv->irq, priv);
+ input_unregister_device(priv->input);
+ kfree(priv);
+ g_priv = NULL;
+ return 0;
+}
+
+/* This structure describe a list of supported slave chips */
+static const struct i2c_device_id ar1020_i2c_id[] = {
+ { "ar1020_i2c", 0 },
+ { }
+};
+
+/*
+ * This is the initial set of information the kernel has
+ * before probing drivers on the system
+ */
+static struct i2c_driver ar1020_i2c_driver = {
+ .driver = {
+ .name = "ar1020_i2c",
+ },
+ .probe = ar1020_i2c_probe,
+ .remove = ar1020_i2c_remove,
+ /*
+ * suspend/resume functions not needed since controller automatically
+ * put's itself to sleep mode after configurable short period of time
+ */
+ .suspend = NULL,
+ .resume = NULL,
+ .id_table = ar1020_i2c_id,
+};
+
+/*
+ * This function is called during startup even if the platform specific
+ * files have not been setup yet.
+ */
+static int __init ar1020_i2c_init(void)
+{
+ int retval;
+
+ pr_debug("AR1020 I2C: ar1020_i2c_init: begin\n");
+ strcpy(receiveBuffer, "");
+ strcpy(sendBuffer, "");
+
+ /*
+ * Creates a kobject "ar1020" that appears as a sub-directory
+ * under "/sys/kernel".
+ */
+ ar1020_kobj = kobject_create_and_add("ar1020", kernel_kobj);
+ if (!ar1020_kobj) {
+ pr_err("AR1020 I2C: cannot create kobject\n");
+ return -ENOMEM;
+ }
+
+ /* Create the files associated with this kobject */
+ retval = sysfs_create_group(ar1020_kobj, &attr_group);
+ if (retval) {
+ pr_err("AR1020 I2C: error registering ar1020-i2c driver's sysfs interface\n");
+ kobject_put(ar1020_kobj);
+ }
+
+ return i2c_add_driver(&ar1020_i2c_driver);
+}
+
+/*
+ * This function is called after ar1020_i2c_remove() immediately before
+ * being removed from the kernel.
+ */
+static void __exit ar1020_i2c_exit(void)
+{
+ pr_debug("AR1020 I2C: ar1020_i2c_exit begin\n");
+ kobject_put(ar1020_kobj);
+ i2c_del_driver(&ar1020_i2c_driver);
+}
+
+MODULE_AUTHOR("Steve Grahovac <steve.grahovac@microchip.com>");
+MODULE_DESCRIPTION("AR1020 touchscreen I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(ar1020_i2c_init);
+module_exit(ar1020_i2c_exit);
diff --git a/drivers/input/touchscreen/fusion_F0710A.c b/drivers/input/touchscreen/fusion_F0710A.c
new file mode 100644
index 000000000000..7ee34f86dcd0
--- /dev/null
+++ b/drivers/input/touchscreen/fusion_F0710A.c
@@ -0,0 +1,507 @@
+/*
+ * "fusion_F0710A" touchscreen driver
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <linux/gpio.h>
+#include <linux/input/fusion_F0710A.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/of_gpio.h>
+
+
+#include "fusion_F0710A.h"
+
+#define DRV_NAME "fusion_F0710A"
+#define MAX_TOUCHES 2
+
+static struct fusion_F0710A_data fusion_F0710A;
+
+static unsigned short normal_i2c[] = { fusion_F0710A_I2C_SLAVE_ADDR, I2C_CLIENT_END };
+
+static int fusion_F0710A_write_u8(u8 addr, u8 data)
+{
+ return i2c_smbus_write_byte_data(fusion_F0710A.client, addr, data);
+}
+
+static int fusion_F0710A_read_u8(u8 addr)
+{
+ return i2c_smbus_read_byte_data(fusion_F0710A.client, addr);
+}
+
+static int fusion_F0710A_read_block(u8 addr, u8 len, u8 *data)
+{
+ u8 msgbuf0[1] = { addr };
+ u16 slave = fusion_F0710A.client->addr;
+ u16 flags = fusion_F0710A.client->flags;
+ struct i2c_msg msg[2] = { { slave, flags, 1, msgbuf0 },
+ { slave, flags | I2C_M_RD, len, data }
+ };
+
+ return i2c_transfer(fusion_F0710A.client->adapter, msg, ARRAY_SIZE(msg));
+}
+
+static int fusion_F0710A_register_input(void)
+{
+ int ret;
+ struct input_dev *dev;
+
+ dev = fusion_F0710A.input = input_allocate_device();
+ if (dev == NULL)
+ return -ENOMEM;
+
+ dev->name = "fusion_F0710A";
+
+ set_bit(EV_KEY, dev->evbit);
+ set_bit(EV_ABS, dev->evbit);
+ set_bit(EV_SYN, dev->evbit);
+ set_bit(BTN_TOUCH, dev->keybit);
+
+ input_mt_init_slots(dev, MAX_TOUCHES, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_X, 0, fusion_F0710A.info.xres-1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, fusion_F0710A.info.yres-1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+ input_set_abs_params(dev, ABS_X, 0, fusion_F0710A.info.xres-1, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, fusion_F0710A.info.yres-1, 0, 0);
+ input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+
+ ret = input_register_device(dev);
+ if (ret < 0)
+ goto bail1;
+
+ return 0;
+
+bail1:
+ input_free_device(dev);
+ return ret;
+}
+
+static void fusion_F0710A_reset(void)
+{
+ /* Generate a 0 => 1 edge explicitly, and wait for startup... */
+ gpio_set_value(fusion_F0710A.gpio_reset, 0);
+ msleep(10);
+ gpio_set_value(fusion_F0710A.gpio_reset, 1);
+ /* Wait for startup (up to 125ms according to datasheet) */
+ msleep(125);
+}
+
+#define WC_RETRY_COUNT 3
+static int fusion_F0710A_write_complete(void)
+{
+ int ret, i;
+
+ for(i=0; i<WC_RETRY_COUNT; i++)
+ {
+ ret = fusion_F0710A_write_u8(fusion_F0710A_SCAN_COMPLETE, 0);
+ if(ret == 0)
+ break;
+ else {
+ dev_warn(&fusion_F0710A.client->dev,
+ "Write complete failed(%d): %d. Resetting controller...\n", i, ret);
+ fusion_F0710A_reset();
+ }
+ }
+
+ return ret;
+}
+
+#define DATA_START fusion_F0710A_DATA_INFO
+#define DATA_END fusion_F0710A_SEC_TIDTS
+#define DATA_LEN (DATA_END - DATA_START + 1)
+#define DATA_OFF(x) ((x) - DATA_START)
+
+static int fusion_F0710A_read_sensor(void)
+{
+ int ret;
+ u8 data[DATA_LEN];
+
+#define DATA(x) (data[DATA_OFF(x)])
+ /* To ensure data coherency, read the sensor with a single transaction. */
+ ret = fusion_F0710A_read_block(DATA_START, DATA_LEN, data);
+ if (ret < 0) {
+ dev_err(&fusion_F0710A.client->dev,
+ "Read block failed: %d\n", ret);
+
+ return ret;
+ }
+
+ fusion_F0710A.f_num = DATA(fusion_F0710A_DATA_INFO)&0x03;
+
+ fusion_F0710A.y1 = DATA(fusion_F0710A_POS_X1_HI) << 8;
+ fusion_F0710A.y1 |= DATA(fusion_F0710A_POS_X1_LO);
+ fusion_F0710A.x1 = DATA(fusion_F0710A_POS_Y1_HI) << 8;
+ fusion_F0710A.x1 |= DATA(fusion_F0710A_POS_Y1_LO);
+ fusion_F0710A.z1 = DATA(fusion_F0710A_FIR_PRESS);
+ fusion_F0710A.tip1 = DATA(fusion_F0710A_FIR_TIDTS)&0x0f;
+ fusion_F0710A.tid1 = (DATA(fusion_F0710A_FIR_TIDTS)&0xf0)>>4;
+
+
+ fusion_F0710A.y2 = DATA(fusion_F0710A_POS_X2_HI) << 8;
+ fusion_F0710A.y2 |= DATA(fusion_F0710A_POS_X2_LO);
+ fusion_F0710A.x2 = DATA(fusion_F0710A_POS_Y2_HI) << 8;
+ fusion_F0710A.x2 |= DATA(fusion_F0710A_POS_Y2_LO);
+ fusion_F0710A.z2 = DATA(fusion_F0710A_SEC_PRESS);
+ fusion_F0710A.tip2 = DATA(fusion_F0710A_SEC_TIDTS)&0x0f;
+ fusion_F0710A.tid2 =(DATA(fusion_F0710A_SEC_TIDTS)&0xf0)>>4;
+#undef DATA
+
+ return 0;
+}
+
+#define val_cut_max(x, max, reverse) \
+do \
+{ \
+ if(x > max) \
+ x = max; \
+ if(reverse) \
+ x = (max) - (x); \
+} \
+while(0)
+
+static void fusion_F0710A_wq(struct work_struct *work)
+{
+ struct input_dev *dev = fusion_F0710A.input;
+
+ if (fusion_F0710A_read_sensor() < 0)
+ goto restore_irq;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "tip1, tid1, x1, y1, z1 (%x,%x,%d,%d,%d); tip2, tid2, x2, y2, z2 (%x,%x,%d,%d,%d)\n",
+ fusion_F0710A.tip1, fusion_F0710A.tid1, fusion_F0710A.x1, fusion_F0710A.y1, fusion_F0710A.z1,
+ fusion_F0710A.tip2, fusion_F0710A.tid2, fusion_F0710A.x2, fusion_F0710A.y2, fusion_F0710A.z2);
+#endif /* DEBUG */
+
+ val_cut_max(fusion_F0710A.x1, fusion_F0710A.info.xres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.y1, fusion_F0710A.info.yres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.x2, fusion_F0710A.info.xres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.y2, fusion_F0710A.info.yres-1, fusion_F0710A.info.xy_reverse);
+
+ if (fusion_F0710A.tid1) {
+ input_mt_slot(dev, fusion_F0710A.tid1 - 1);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, fusion_F0710A.tip1);
+ if (fusion_F0710A.tip1) {
+ input_report_abs(dev, ABS_MT_POSITION_X, fusion_F0710A.x1);
+ input_report_abs(dev, ABS_MT_POSITION_Y, fusion_F0710A.y1);
+ input_report_abs(dev, ABS_MT_PRESSURE, fusion_F0710A.z1);
+ }
+ }
+
+ if (fusion_F0710A.tid2) {
+ input_mt_slot(dev, fusion_F0710A.tid2 - 1);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, fusion_F0710A.tip2);
+ if (fusion_F0710A.tip2) {
+ input_report_abs(dev, ABS_MT_POSITION_X, fusion_F0710A.x2);
+ input_report_abs(dev, ABS_MT_POSITION_Y, fusion_F0710A.y2);
+ input_report_abs(dev, ABS_MT_PRESSURE, fusion_F0710A.z2);
+ }
+ }
+
+ input_mt_report_pointer_emulation(dev, false);
+ input_sync(dev);
+
+restore_irq:
+ enable_irq(fusion_F0710A.client->irq);
+
+ /* Clear fusion_F0710A interrupt */
+ fusion_F0710A_write_complete();
+}
+static DECLARE_WORK(fusion_F0710A_work, fusion_F0710A_wq);
+
+static irqreturn_t fusion_F0710A_interrupt(int irq, void *dev_id)
+{
+ disable_irq_nosync(fusion_F0710A.client->irq);
+
+ queue_work(fusion_F0710A.workq, &fusion_F0710A_work);
+
+ return IRQ_HANDLED;
+}
+
+const static u8* g_ver_product[4] = {
+ "10Z8", "70Z7", "43Z6", ""
+};
+
+static int of_fusion_F0710A_get_pins(struct device_node *np,
+ unsigned int *int_pin, unsigned int *reset_pin)
+{
+ if (of_gpio_count(np) < 2)
+ return -ENODEV;
+
+ *int_pin = of_get_gpio(np, 0);
+ *reset_pin = of_get_gpio(np, 1);
+
+ if (!gpio_is_valid(*int_pin) || !gpio_is_valid(*reset_pin)) {
+ pr_err("%s: invalid GPIO pins, int=%d/reset=%d\n",
+ np->full_name, *int_pin, *reset_pin);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int fusion_F0710A_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct fusion_f0710a_init_data *pdata = i2c->dev.platform_data;
+ int ret;
+ u8 ver_product, ver_id;
+ u32 version;
+
+ if (np != NULL) {
+ pdata = i2c->dev.platform_data =
+ devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+ if (pdata == NULL) {
+ dev_err(&i2c->dev, "No platform data for Fusion driver\n");
+ return -ENODEV;
+ }
+ /* the dtb did the pinmuxing for us */
+ pdata->pinmux_fusion_pins = NULL;
+ ret = of_fusion_F0710A_get_pins(i2c->dev.of_node,
+ &pdata->gpio_int, &pdata->gpio_reset);
+ if (ret)
+ return ret;
+ }
+ else if (pdata == NULL) {
+ dev_err(&i2c->dev, "No platform data for Fusion driver\n");
+ return -ENODEV;
+ }
+
+ /* Request pinmuxing, if necessary */
+ if (pdata->pinmux_fusion_pins != NULL) {
+ ret = pdata->pinmux_fusion_pins();
+ if (ret < 0) {
+ dev_err(&i2c->dev, "muxing GPIOs failed\n");
+ return -ENODEV;
+ }
+ }
+
+ if ((gpio_request(pdata->gpio_int, "Fusion pen down interrupt") == 0) &&
+ (gpio_direction_input(pdata->gpio_int) == 0)) {
+ gpio_export(pdata->gpio_int, 0);
+ } else {
+ dev_warn(&i2c->dev, "Could not obtain GPIO for Fusion pen down\n");
+ return -ENODEV;
+ }
+
+ if ((gpio_request(pdata->gpio_reset, "Fusion reset") == 0) &&
+ (gpio_direction_output(pdata->gpio_reset, 1) == 0)) {
+ fusion_F0710A.gpio_reset = pdata->gpio_reset;
+ fusion_F0710A_reset();
+ gpio_export(pdata->gpio_reset, 0);
+ } else {
+ dev_warn(&i2c->dev, "Could not obtain GPIO for Fusion reset\n");
+ ret = -ENODEV;
+ goto bail0;
+ }
+
+ /* Use Pen Down GPIO as sampling interrupt */
+ i2c->irq = gpio_to_irq(pdata->gpio_int);
+ irq_set_irq_type(i2c->irq, IRQ_TYPE_LEVEL_HIGH);
+
+ if(!i2c->irq)
+ {
+ dev_err(&i2c->dev, "fusion_F0710A irq < 0 \n");
+ ret = -ENOMEM;
+ goto bail1;
+ }
+
+ /* Attach the I2C client */
+ fusion_F0710A.client = i2c;
+ i2c_set_clientdata(i2c, &fusion_F0710A);
+
+ dev_info(&i2c->dev, "Touchscreen registered with bus id (%d) with slave address 0x%x\n",
+ i2c_adapter_id(fusion_F0710A.client->adapter), fusion_F0710A.client->addr);
+
+ /* Read out a lot of registers */
+ ret = fusion_F0710A_read_u8(fusion_F0710A_VIESION_INFO_LO);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "query failed: %d\n", ret);
+ goto bail1;
+ }
+ ver_product = (((u8)ret) & 0xc0) >> 6;
+ version = (10 + ((((u32)ret)&0x30) >> 4)) * 100000;
+ version += (((u32)ret)&0xf) * 1000;
+ /* Read out a lot of registers */
+ ret = fusion_F0710A_read_u8(fusion_F0710A_VIESION_INFO);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "query failed: %d\n", ret);
+ goto bail1;
+ }
+ ver_id = ((u8)(ret) & 0x6) >> 1;
+ version += ((((u32)ret) & 0xf8) >> 3) * 10;
+ version += (((u32)ret) & 0x1) + 1; /* 0 is build 1, 1 is build 2 */
+ dev_info(&i2c->dev, "version product %s(%d)\n", g_ver_product[ver_product] ,ver_product);
+ dev_info(&i2c->dev, "version id %s(%d)\n", ver_id ? "1.4" : "1.0", ver_id);
+ dev_info(&i2c->dev, "version series (%d)\n", version);
+
+ switch(ver_product)
+ {
+ case fusion_F0710A_VIESION_07: /* 7 inch */
+ fusion_F0710A.info.xres = fusion_F0710A07_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A07_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A07_REV;
+ break;
+ case fusion_F0710A_VIESION_43: /* 4.3 inch */
+ fusion_F0710A.info.xres = fusion_F0710A43_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A43_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A43_REV;
+ break;
+ default: /* fusion_F0710A_VIESION_10 10 inch */
+ fusion_F0710A.info.xres = fusion_F0710A10_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A10_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A10_REV;
+ break;
+ }
+
+ /* Register the input device. */
+ ret = fusion_F0710A_register_input();
+ if (ret < 0) {
+ dev_err(&i2c->dev, "can't register input: %d\n", ret);
+ goto bail1;
+ }
+
+ /* Create a worker thread */
+ fusion_F0710A.workq = create_singlethread_workqueue(DRV_NAME);
+ if (fusion_F0710A.workq == NULL) {
+ dev_err(&i2c->dev, "can't create work queue\n");
+ ret = -ENOMEM;
+ goto bail2;
+ }
+
+
+ /* Register for the interrupt and enable it. Our handler will
+ * start getting invoked after this call. */
+ ret = request_irq(i2c->irq, fusion_F0710A_interrupt, IRQF_TRIGGER_RISING,
+ i2c->name, &fusion_F0710A);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "can't get irq %d: %d\n", i2c->irq, ret);
+ goto bail3;
+ }
+ /* clear the irq first */
+ ret = fusion_F0710A_write_u8(fusion_F0710A_SCAN_COMPLETE, 0);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Clear irq failed: %d\n", ret);
+ goto bail4;
+ }
+
+ return 0;
+
+bail4:
+ free_irq(i2c->irq, &fusion_F0710A);
+
+bail3:
+ destroy_workqueue(fusion_F0710A.workq);
+ fusion_F0710A.workq = NULL;
+
+bail2:
+ input_unregister_device(fusion_F0710A.input);
+bail1:
+ gpio_free(pdata->gpio_reset);
+bail0:
+ gpio_free(pdata->gpio_int);
+
+ return ret;
+}
+
+static int __maybe_unused fusion_F0710A_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+ disable_irq(i2c->irq);
+ flush_workqueue(fusion_F0710A.workq);
+
+ return 0;
+}
+
+static int __maybe_unused fusion_F0710A_resume(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+ enable_irq(i2c->irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(fusion_F0710A_pm_ops,
+ fusion_F0710A_suspend, fusion_F0710A_resume);
+
+static int fusion_F0710A_remove(struct i2c_client *i2c)
+{
+ struct fusion_f0710a_init_data *pdata = i2c->dev.platform_data;
+
+ gpio_free(pdata->gpio_int);
+ gpio_free(pdata->gpio_reset);
+ destroy_workqueue(fusion_F0710A.workq);
+ free_irq(i2c->irq, &fusion_F0710A);
+ input_unregister_device(fusion_F0710A.input);
+ i2c_set_clientdata(i2c, NULL);
+
+ dev_info(&i2c->dev, "driver removed\n");
+
+ return 0;
+}
+
+static struct i2c_device_id fusion_F0710A_id[] = {
+ {"fusion_F0710A", 0},
+ {},
+};
+
+static const struct of_device_id fusion_F0710A_dt_ids[] = {
+ {
+ .compatible = "touchrevolution,fusion-f0710a",
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, fusion_F0710A_dt_ids);
+
+static struct i2c_driver fusion_F0710A_i2c_drv = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .pm = &fusion_F0710A_pm_ops,
+ .of_match_table = fusion_F0710A_dt_ids,
+ },
+ .probe = fusion_F0710A_probe,
+ .remove = fusion_F0710A_remove,
+ .id_table = fusion_F0710A_id,
+ .address_list = normal_i2c,
+};
+
+
+static int __init fusion_F0710A_init( void )
+{
+ int ret;
+
+ memset(&fusion_F0710A, 0, sizeof(fusion_F0710A));
+
+ /* Probe for fusion_F0710A on I2C. */
+ ret = i2c_add_driver(&fusion_F0710A_i2c_drv);
+ if (ret < 0) {
+ printk(KERN_WARNING DRV_NAME " can't add i2c driver: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static void __exit fusion_F0710A_exit( void )
+{
+ i2c_del_driver(&fusion_F0710A_i2c_drv);
+}
+module_init(fusion_F0710A_init);
+module_exit(fusion_F0710A_exit);
+
+MODULE_DESCRIPTION("fusion_F0710A Touchscreen Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/input/touchscreen/fusion_F0710A.h b/drivers/input/touchscreen/fusion_F0710A.h
new file mode 100644
index 000000000000..3e5af9e72b78
--- /dev/null
+++ b/drivers/input/touchscreen/fusion_F0710A.h
@@ -0,0 +1,88 @@
+/*
+ * "fusion_F0710A" touchscreen driver
+ *
+ * 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.
+ */
+
+/* I2C slave address */
+#define fusion_F0710A_I2C_SLAVE_ADDR 0x10
+
+/* I2C registers */
+#define fusion_F0710A_DATA_INFO 0x00
+
+/* First Point*/
+#define fusion_F0710A_POS_X1_HI 0x01 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_X1_LO 0x02 /* 16-bit register, LSB */
+#define fusion_F0710A_POS_Y1_HI 0x03 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_Y1_LO 0x04 /* 16-bit register, LSB */
+#define fusion_F0710A_FIR_PRESS 0X05
+#define fusion_F0710A_FIR_TIDTS 0X06
+
+/* Second Point */
+#define fusion_F0710A_POS_X2_HI 0x07 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_X2_LO 0x08 /* 16-bit register, LSB */
+#define fusion_F0710A_POS_Y2_HI 0x09 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_Y2_LO 0x0A /* 16-bit register, LSB */
+#define fusion_F0710A_SEC_PRESS 0x0B
+#define fusion_F0710A_SEC_TIDTS 0x0C
+
+#define fusion_F0710A_VIESION_INFO_LO 0X0E
+#define fusion_F0710A_VIESION_INFO 0X0F
+
+#define fusion_F0710A_RESET 0x10
+#define fusion_F0710A_SCAN_COMPLETE 0x11
+
+
+#define fusion_F0710A_VIESION_10 0
+#define fusion_F0710A_VIESION_07 1
+#define fusion_F0710A_VIESION_43 2
+
+/* fusion_F0710A 10 inch panel */
+#define fusion_F0710A10_XMAX 2275
+#define fusion_F0710A10_YMAX 1275
+#define fusion_F0710A10_REV 1
+
+/* fusion_F0710A 7 inch panel */
+#define fusion_F0710A07_XMAX 1500
+#define fusion_F0710A07_YMAX 900
+#define fusion_F0710A07_REV 0
+
+/* fusion_F0710A 4.3 inch panel */
+#define fusion_F0710A43_XMAX 900
+#define fusion_F0710A43_YMAX 500
+#define fusion_F0710A43_REV 0
+
+#define fusion_F0710A_SAVE_PT1 0x1
+#define fusion_F0710A_SAVE_PT2 0x2
+
+
+
+/* fusion_F0710A touch screen information */
+struct fusion_F0710A_info {
+ int xres; /* x resolution */
+ int yres; /* y resolution */
+ int xy_reverse; /* if need reverse in the x,y value x=xres-1-x, y=yres-1-y*/
+};
+
+struct fusion_F0710A_data {
+ struct fusion_F0710A_info info;
+ struct i2c_client *client;
+ struct workqueue_struct *workq;
+ struct input_dev *input;
+ int gpio_reset;
+ u16 x1;
+ u16 y1;
+ u8 z1;
+ u8 tip1;
+ u8 tid1;
+ u16 x2;
+ u16 y2;
+ u8 z2;
+ u8 tip2;
+ u8 tid2;
+ u8 f_num;
+ u8 save_points;
+};
+
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 16cbff0e9b0b..24c2e09ab984 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -150,6 +150,7 @@ config VIDEO_MX8_CAPTURE
config VIDEO_MXC_CAPTURE
tristate "MXC Video For Linux Video Capture"
depends on VIDEO_V4L2
+ select VIDEOBUF2_DMA_CONTIG
---help---
This is the video4linux2 capture driver based on i.MX video-in module.
@@ -182,6 +183,16 @@ config VIDEO_TI_CAL
In TI Technical Reference Manual this module is referred as
Camera Interface Subsystem (CAMSS).
+config VIDEO_ECAM
+ tristate "e-con camera sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ ---help---
+ This config is used to enable codes which are used to
+ support econ camera and to disable ISI control codes.
+
+ To compile this driver as a module, choose M here: the module
+ will be called based on sensor name.
+
endif # V4L_PLATFORM_DRIVERS
menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/imx8/Kconfig b/drivers/media/platform/imx8/Kconfig
index 9e33a590bb72..2f3ea43bb789 100644
--- a/drivers/media/platform/imx8/Kconfig
+++ b/drivers/media/platform/imx8/Kconfig
@@ -12,6 +12,20 @@ config IMX8_JPEG
select VIDEOBUF2_DMA_CONTIG
default m
+config MXC_CAMERA_AR0521
+ tristate "AR0521 Camera driver support"
+ depends on I2C && VIDEO_ECAM
+ default y
+ help
+ Enable support for video4linux camera sensor driver for eCAM50_CUIMX8
+
+config MXC_CAMERA_AR1335
+ tristate "AR1335 Camera driver support"
+ depends on I2C && VIDEO_ECAM
+ default y
+ help
+ Enable support for video4linux camera sensor driver for eCAM131_CUIMX8
+
endmenu
endif #VIDEO_MX8_CAPTURE
diff --git a/drivers/media/platform/imx8/Makefile b/drivers/media/platform/imx8/Makefile
index 15259cf9c13f..b0226f245299 100644
--- a/drivers/media/platform/imx8/Makefile
+++ b/drivers/media/platform/imx8/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_IMX8_MIPI_CSI2_YAV) += mxc-mipi-csi2_yav.o
mxc-jpeg-encdec-objs := mxc-jpeg-hw.o mxc-jpeg.o
obj-$(CONFIG_IMX8_JPEG) += mxc-jpeg-encdec.o
+obj-$(CONFIG_MXC_CAMERA_AR0521) += ar0521.o
+obj-$(CONFIG_MXC_CAMERA_AR1335) += ar1335.o
diff --git a/drivers/media/platform/imx8/ar0521.c b/drivers/media/platform/imx8/ar0521.c
new file mode 100644
index 000000000000..eb2edd101aa1
--- /dev/null
+++ b/drivers/media/platform/imx8/ar0521.c
@@ -0,0 +1,3619 @@
+/*
+ * ar0521.c - AR0521 sensor driver
+ * Copyright (c) 2020-2021, e-con Systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#include "ar0521.h"
+#include "mcu_firmware.h"
+
+/*
+#define AR0521_DEBUG 1
+*/
+
+/*!
+ * Maintains the information on the current state of the sensor.
+ */
+static struct ar0521 ar0521_data;
+
+static int pwdn_gpio, reset_gpio;
+
+int gpios_available(void)
+{
+ return (pwdn_gpio >= 0) && (reset_gpio >= 0);
+}
+
+/**********************************************************************
+ *
+ * START of AR0521 related code
+ *
+ **********************************************************************
+ */
+
+static int ar0521_write(struct i2c_client *client, u8 * val, u32 count)
+{
+ int ret;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = count,
+ .buf = val,
+ };
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed writing register.\n");
+ dev_err(&client->dev, "addr: %x; val = %hhu, ret = %d!\n",
+ client->addr, *val, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ar0521_read(struct i2c_client *client, u8 * val, u32 count)
+{
+ int ret;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = val,
+ };
+
+ msg.flags = I2C_M_RD;
+ msg.len = count;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+ err:
+ dev_err(&client->dev, "Failed reading register ret = %d!\n", ret);
+ return ret;
+}
+
+/*
+ * The MCU specific functions below depend on the sensor-specific
+ * functions above.
+ */
+
+/*
+ * ---------------------------------------------------------
+ * START of MCU realed functions
+ * ---------------------------------------------------------
+ */
+
+/*
+ * NOTE about modularizing this MCU related function.
+ *
+ * - The functions:
+ *
+ * x mcu_get_fw_version
+ * x mcu_bload_get_version
+ * x mcu_bload_erase_flash
+ * x mcu_bload_parse_send_cmd
+ * x mcu_bload_go
+ * x mcu_bload_read
+ * x mcu_count_or_list_ctrls
+ * x mcu_count_or_list_fmts
+ * x mcu_get_sensor_id
+ * x mcu_get_ctrl_ui
+ * x mcu_stream_config
+ * x mcu_isp_power_down
+ * x mcu_isp_power_wakeup
+ * x mcu_set_ctrl
+ * x mcu_get_ctrl
+ *
+ * seem to directly use platform specific functions:
+ *
+ * x ar0521_write
+ * x ar0521_read
+ *
+ * This could be passed in as a function pointer.
+ */
+
+static unsigned short int mcu_bload_calc_crc16(unsigned char *buf, int len)
+{
+ unsigned short int crc = 0;
+ int i = 0;
+
+ if (!buf || !(buf + len))
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ crc ^= buf[i];
+ }
+
+ return crc;
+}
+
+static int mcu_bload_ascii2hex(unsigned char ascii)
+{
+ if (ascii <= '9') {
+ return (ascii - '0');
+ } else if ((ascii >= 'a') && (ascii <= 'f')) {
+ return (0xA + (ascii - 'a'));
+ } else if ((ascii >= 'A') && (ascii <= 'F')) {
+ return (0xA + (ascii - 'A'));
+ }
+ return -1;
+}
+
+static unsigned char errorcheck(char *data, unsigned int len)
+{
+ unsigned int i = 0;
+ unsigned char crc = 0x00;
+
+ for (i = 0; i < len; i++) {
+ crc ^= data[i];
+ }
+
+ return crc;
+}
+
+/*
+ * mcu_get_fw_version:
+ *
+ * Read the firmware version from the MCU.
+ *
+ * A success value (0) is returned when the MCU version could be successfully read.
+ * else a negative value indicating error is returned.
+ */
+static int mcu_get_fw_version(struct i2c_client *client, unsigned char *fw_version)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ int ret = 0, err = 0, loop;
+ /* Query firmware version from MCU */
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_VERSION;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ err = ar0521_write(client, mc_data, TX_LEN_PKT);
+ if (err != 0)
+ {
+ dev_err(&client->dev, "MCU CMD ID version Error- %d\n", err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_VERSION;
+ err = ar0521_write(client, mc_data, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID Write PKT fw Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID Read PKT fw Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID fw Version Error CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID fw Errcode - 0x%02x \n", __func__,
+ __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Read the actual version from MCU*/
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) + HEADER_FOOTER_SIZE;
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Read Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data[2], 32);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Version CRC ERROR 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Read Payload Error - 0x%02x \n", __func__,
+ __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ for (loop = 0 ; loop < VERSION_SIZE ; loop++ )
+ *(fw_version+loop) = mc_ret_data[2+loop];
+
+ ret = ERRCODE_SUCCESS;
+exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+/**
+ * mcu_verify_fw_version:
+ *
+ * Verify the firmware version obtained from the MCU and that found in the
+ * firmware text file present in our driver.
+ *
+ * The return value after verification is as follows:
+ *
+ * - If the version number matches a success value (0) is returned.
+ *
+ * - In case the version number mismatches, a negative value indicating error
+ * is returned.
+ *
+ * - In case the force update bit is set in firmware version in the text
+ * file, a positive value is returned.
+ */
+static int mcu_verify_fw_version(const unsigned char *const fw_version)
+{
+ int loop, i = 0, ret;
+ char txt_fw_version[32] = {0};
+ unsigned long txt_fw_pos = ARRAY_SIZE(g_mcu_fw_buf)-VERSION_FILE_OFFSET;
+
+ /* Get Text Firmware version*/
+ for(loop = txt_fw_pos; loop < (txt_fw_pos+64); loop=loop+2) {
+ *(txt_fw_version+i) = (mcu_bload_ascii2hex(g_mcu_fw_buf[loop]) << 4 |
+ mcu_bload_ascii2hex(g_mcu_fw_buf[loop+1]));
+ i++;
+ }
+
+ /* Check for forced/always update field in the text firmware version*/
+ if(txt_fw_version[17] == '1') {
+
+#ifdef AR0521_DEBUG
+ pr_info("Forced Update Enabled - Firmware Version - (%.32s) \n",
+ fw_version);
+#endif
+
+ ret = 2;
+ }
+ else {
+ for(i = 0; i < VERSION_SIZE; i++) {
+ if(txt_fw_version[i] != fw_version[i]) {
+
+ pr_info("Previous Firmware Version - (%.32s)\n", fw_version);
+
+ ret = -1;
+ break;
+ }
+ }
+
+ if (i == VERSION_SIZE)
+ ret = ERRCODE_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int mcu_bload_get_version(struct i2c_client *client)
+{
+ int ret = 0;
+
+ /*----------------------------- GET VERSION -------------------- */
+
+ /* Write Get Version CMD */
+ g_bload_buf[0] = BL_GET_VERSION;
+ g_bload_buf[1] = ~(BL_GET_VERSION);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != 'y') {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed\n");
+ return -1;
+ }
+
+ /* ---------------- GET VERSION END ------------------- */
+
+ return 0;
+}
+
+static int mcu_bload_erase_flash(struct i2c_client *client)
+{
+ unsigned short int pagenum = 0x0000;
+ int ret = 0, i = 0, checksum = 0;
+
+ /* --------------- ERASE FLASH --------------------- */
+
+ for (i = 0; i < NUM_ERASE_CYCLES; i++) {
+
+ checksum = 0x00;
+ /* Write Erase Pages CMD */
+ g_bload_buf[0] = BL_ERASE_MEM_NS;
+ g_bload_buf[1] = ~(BL_ERASE_MEM_NS);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf[0] = (MAX_PAGES - 1) >> 8;
+ g_bload_buf[1] = (MAX_PAGES - 1) & 0xFF;
+ g_bload_buf[2] = g_bload_buf[0] ^ g_bload_buf[1];
+
+ ret = ar0521_write(client, g_bload_buf, 3);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ for (pagenum = 0; pagenum < MAX_PAGES; pagenum++) {
+ g_bload_buf[(2 * pagenum)] =
+ (pagenum + (i * MAX_PAGES)) >> 8;
+ g_bload_buf[(2 * pagenum) + 1] =
+ (pagenum + (i * MAX_PAGES)) & 0xFF;
+ checksum =
+ checksum ^ g_bload_buf[(2 * pagenum)] ^
+ g_bload_buf[(2 * pagenum) + 1];
+ }
+ g_bload_buf[2 * MAX_PAGES] = checksum;
+
+ ret = ar0521_write(client, g_bload_buf, (2 * MAX_PAGES) + 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ poll_busy:
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] == RESP_BUSY)
+ goto poll_busy;
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info(" ERASE Sector %d success !! \n", i + 1);
+#endif
+ }
+
+ /* ------------ ERASE FLASH END ----------------------- */
+
+ return 0;
+}
+
+static unsigned char mcu_bload_inv_checksum(unsigned char *buf, int len)
+{
+ unsigned int checksum = 0x00;
+ int i = 0;
+
+ if (!buf || !(buf + len))
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ checksum = (checksum + buf[i]);
+ }
+
+ checksum &= (0xFF);
+ return (~(checksum) + 1);
+}
+
+static int mcu_bload_parse_send_cmd(struct i2c_client *client,
+ unsigned char *bytearray, int rec_len)
+{
+ IHEX_RECORD *ihex_rec = NULL;
+ unsigned char checksum = 0, calc_checksum = 0;
+ int i = 0, ret = 0;
+
+ if (!bytearray)
+ return -1;
+
+ ihex_rec = (IHEX_RECORD *) bytearray;
+ ihex_rec->addr = htons(ihex_rec->addr);
+
+ checksum = bytearray[rec_len - 1];
+
+ calc_checksum = mcu_bload_inv_checksum(bytearray, rec_len - 1);
+ if (checksum != calc_checksum) {
+ dev_err(&client->dev," Invalid Checksum 0x%02x != 0x%02x !! \n",
+ checksum, calc_checksum);
+ return -1;
+ }
+
+ if ((ihex_rec->rectype == REC_TYPE_ELA)
+ && (ihex_rec->addr == 0x0000)
+ && (ihex_rec->datasize = 0x02)) {
+ /* Upper 32-bit configuration */
+ g_bload_flashaddr = (ihex_rec->recdata[0] <<
+ 24) | (ihex_rec->recdata[1]
+ << 16);
+#ifdef AR0521_DEBUG
+ pr_info("Updated Flash Addr = 0x%08x \n",
+ g_bload_flashaddr);
+#endif
+
+ } else if (ihex_rec->rectype == REC_TYPE_DATA) {
+ /* Flash Data into Flashaddr */
+
+ g_bload_flashaddr =
+ (g_bload_flashaddr & 0xFFFF0000) | (ihex_rec->addr);
+ g_bload_crc16 ^=
+ mcu_bload_calc_crc16(ihex_rec->recdata, ihex_rec->datasize);
+
+ /* Write Erase Pages CMD */
+ g_bload_buf[0] = BL_WRITE_MEM_NS;
+ g_bload_buf[1] = ~(BL_WRITE_MEM_NS);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf[0] = (g_bload_flashaddr & 0xFF000000) >> 24;
+ g_bload_buf[1] = (g_bload_flashaddr & 0x00FF0000) >> 16;
+ g_bload_buf[2] = (g_bload_flashaddr & 0x0000FF00) >> 8;
+ g_bload_buf[3] = (g_bload_flashaddr & 0x000000FF);
+ g_bload_buf[4] =
+ g_bload_buf[0] ^ g_bload_buf[1] ^ g_bload_buf[2] ^
+ g_bload_buf[3];
+
+ ret = ar0521_write(client, g_bload_buf, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf[0] = ihex_rec->datasize - 1;
+ checksum = g_bload_buf[0];
+ for (i = 0; i < ihex_rec->datasize; i++) {
+ g_bload_buf[i + 1] = ihex_rec->recdata[i];
+ checksum ^= g_bload_buf[i + 1];
+ }
+
+ g_bload_buf[i + 1] = checksum;
+
+ ret = ar0521_write(client, g_bload_buf, i + 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ poll_busy:
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] == RESP_BUSY)
+ goto poll_busy;
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ } else if (ihex_rec->rectype == REC_TYPE_SLA) {
+ /* Update Instruction pointer to this address */
+
+ } else if (ihex_rec->rectype == REC_TYPE_EOF) {
+ /* End of File - Issue I2C Go Command */
+ return 0;
+ } else {
+
+ /* Unhandled Type */
+ dev_err(&client->dev,"Unhandled Command Type \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_bload_update_fw(struct i2c_client *client)
+{
+ /* exclude NULL character at end of string */
+ unsigned long hex_file_size = ARRAY_SIZE(g_mcu_fw_buf) - 1;
+ unsigned char wbuf[MAX_BUF_LEN];
+ int i = 0, recindex = 0, ret = 0;
+
+ for (i = 0; i < hex_file_size; i++) {
+ if ((recindex == 0) && (g_mcu_fw_buf[i] == ':')) {
+ /* pr_info("Start of a Record \n"); */
+ } else if (g_mcu_fw_buf[i] == CR) {
+ /* No Implementation */
+ } else if (g_mcu_fw_buf[i] == LF) {
+ if (recindex == 0) {
+ /* Parsing Complete */
+ break;
+ }
+
+ /* Analyze Packet and Send Commands */
+ ret = mcu_bload_parse_send_cmd(client, wbuf, recindex);
+ if (ret < 0) {
+ dev_err(&client->dev,"Error in Processing Commands \n");
+ break;
+ }
+
+ recindex = 0;
+
+ } else {
+ /* Parse Rec Data */
+ if ((ret = mcu_bload_ascii2hex(g_mcu_fw_buf[i])) < 0) {
+ dev_err(&client->dev,
+ "Invalid Character - 0x%02x !! \n",
+ g_mcu_fw_buf[i]);
+ break;
+ }
+
+ wbuf[recindex] = (0xF0 & (ret << 4));
+ i++;
+
+ if ((ret = mcu_bload_ascii2hex(g_mcu_fw_buf[i])) < 0) {
+ dev_err(&client->dev,
+ "Invalid Character - 0x%02x !!!! \n",
+ g_mcu_fw_buf[i]);
+ break;
+ }
+
+ wbuf[recindex] |= (0x0F & ret);
+ recindex++;
+ }
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info("Program FLASH Success !! - CRC = 0x%04x \n",
+ g_bload_crc16);
+#endif
+
+ /* ------------ PROGRAM FLASH END ----------------------- */
+
+ return ret;
+}
+
+static int mcu_bload_read(struct i2c_client *client,
+ unsigned int g_bload_flashaddr, char *bytearray,
+ unsigned int len)
+{
+ int ret = 0;
+
+ g_bload_buf[0] = BL_READ_MEM;
+ g_bload_buf[1] = ~(BL_READ_MEM);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf[0] = (g_bload_flashaddr & 0xFF000000) >> 24;
+ g_bload_buf[1] = (g_bload_flashaddr & 0x00FF0000) >> 16;
+ g_bload_buf[2] = (g_bload_flashaddr & 0x0000FF00) >> 8;
+ g_bload_buf[3] = (g_bload_flashaddr & 0x000000FF);
+ g_bload_buf[4] =
+ g_bload_buf[0] ^ g_bload_buf[1] ^ g_bload_buf[2] ^ g_bload_buf[3];
+
+ ret = ar0521_write(client, g_bload_buf, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf[0] = len - 1;
+ g_bload_buf[1] = ~(len - 1);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ ret = ar0521_read(client, bytearray, len);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_bload_verify_flash(struct i2c_client *client,
+ unsigned short int orig_crc)
+{
+ char bytearray[FLASH_READ_LEN];
+ unsigned short int calc_crc = 0;
+ unsigned int flash_addr = FLASH_START_ADDRESS, i = 0;
+
+ while ((i + FLASH_READ_LEN) <= FLASH_SIZE) {
+ memset(bytearray, 0x0, FLASH_READ_LEN);
+
+ if (mcu_bload_read(
+ client, flash_addr + i, bytearray, FLASH_READ_LEN) < 0) {
+ dev_err(&client->dev," i2c_bload_read FAIL !! \n");
+ return -1;
+ }
+
+ calc_crc ^= mcu_bload_calc_crc16(bytearray, FLASH_READ_LEN);
+ i += FLASH_READ_LEN;
+ }
+
+ if ((FLASH_SIZE - i) > 0) {
+ memset(bytearray, 0x0, FLASH_READ_LEN);
+
+ if (mcu_bload_read(
+ client, flash_addr + i, bytearray, (FLASH_SIZE - i)
+ ) < 0) {
+ dev_err(&client->dev," i2c_bload_read FAIL !! \n");
+ return -1;
+ }
+
+ calc_crc ^= mcu_bload_calc_crc16(bytearray, FLASH_READ_LEN);
+ }
+
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," CRC verification fail !! 0x%04x != 0x%04x \n",
+ orig_crc, calc_crc);
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info(" CRC Verification Success 0x%04x == 0x%04x \n",
+ orig_crc, calc_crc);
+#endif
+
+ return 0;
+}
+
+static int mcu_bload_go(struct i2c_client *client)
+{
+ int ret = 0;
+
+ g_bload_buf[0] = BL_GO;
+ g_bload_buf[1] = ~(BL_GO);
+
+ ret = ar0521_write(client, g_bload_buf, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Failed Read 1 \n");
+ return -1;
+ }
+
+ /* Start Address */
+ g_bload_buf[0] = (FLASH_START_ADDRESS & 0xFF000000) >> 24;
+ g_bload_buf[1] = (FLASH_START_ADDRESS & 0x00FF0000) >> 16;
+ g_bload_buf[2] = (FLASH_START_ADDRESS & 0x0000FF00) >> 8;
+ g_bload_buf[3] = (FLASH_START_ADDRESS & 0x000000FF);
+ g_bload_buf[4] =
+ g_bload_buf[0] ^ g_bload_buf[1] ^ g_bload_buf[2] ^ g_bload_buf[3];
+
+ ret = ar0521_write(client, g_bload_buf, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ ret = ar0521_read(client, g_bload_buf, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Failed Read 1 \n");
+ return -1;
+ }
+
+ if (g_bload_buf[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_fw_update(struct i2c_client *client, unsigned char *mcu_fw_version)
+{
+ int ret = 0;
+ g_bload_crc16 = 0;
+
+ /*
+ * TODO: Is this necessary? It seems redundant as it's already called before
+ * calling this function.
+ */
+ /* Read Firmware version from bootloader MCU */
+ ret = mcu_bload_get_version(client);
+ if (ret < 0) {
+ dev_err(&client->dev," Error in Get Version \n");
+ goto exit;
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info(" Get Version SUCCESS !! \n");
+#endif
+
+ /* Erase firmware present in the MCU and flash new firmware*/
+ ret = mcu_bload_erase_flash(client);
+ if (ret < 0) {
+ dev_err(&client->dev," Error in Erase Flash \n");
+ goto exit;
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info("Erase Flash Success !! \n");
+#endif
+
+ /* Read the firmware present in the text file */
+ if ((ret = mcu_bload_update_fw(client)) < 0) {
+ dev_err(&client->dev," Write Flash FAIL !! \n");
+ goto exit;
+ }
+
+ /* Verify the checksum for the update firmware */
+ if ((ret = mcu_bload_verify_flash(client, g_bload_crc16)) < 0) {
+ dev_err(&client->dev," verify_flash FAIL !! \n");
+ goto exit;
+ }
+
+ /* Reverting from bootloader mode */
+ /* I2C GO Command */
+ if ((ret = mcu_bload_go(client)) < 0) {
+ dev_err(&client->dev," i2c_bload_go FAIL !! \n");
+ goto exit;
+ }
+
+ if(mcu_fw_version) {
+
+#ifdef AR0521_DEBUG
+ pr_info("(%s) - Firmware Updated - (%.32s)\n",
+ __func__, mcu_fw_version);
+#endif
+
+ }
+ exit:
+ return ret;
+}
+
+static int mcu_count_or_list_ctrls(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_cam_ctrl, int *numctrls)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ uint16_t index = 0;
+ int ret = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ /* Array of Ctrl Info */
+ while (1) {
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL_INFO;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL_INFO;
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+ err = ar0521_write(client, mc_data, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (((mc_ret_data[2] << 8) | mc_ret_data[3]) == 0) {
+ *numctrls = index;
+ break;
+ }
+
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) +
+ HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data[2],
+ payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if(mcu_cam_ctrl != NULL) {
+ int sorted_elem = index - 1, elem = index;
+
+ /* append ctrl info in array */
+ mcu_cam_ctrl[index].ctrl_id =
+ mc_ret_data[2] << 24 | mc_ret_data[3] << 16 | mc_ret_data[4]
+ << 8 | mc_ret_data[5];
+ mcu_cam_ctrl[index].ctrl_type = mc_ret_data[6];
+
+ switch (mcu_cam_ctrl[index].ctrl_type) {
+ case CTRL_STANDARD:
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_min =
+ mc_ret_data[7] << 24 | mc_ret_data[8] << 16
+ | mc_ret_data[9] << 8 | mc_ret_data[10];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_max =
+ mc_ret_data[11] << 24 | mc_ret_data[12] <<
+ 16 | mc_ret_data[13]
+ << 8 | mc_ret_data[14];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_def =
+ mc_ret_data[15] << 24 | mc_ret_data[16] <<
+ 16 | mc_ret_data[17]
+ << 8 | mc_ret_data[18];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_step =
+ mc_ret_data[19] << 24 | mc_ret_data[20] <<
+ 16 | mc_ret_data[21]
+ << 8 | mc_ret_data[22];
+
+ mcu_cam_ctrl[index].mcu_ctrl_index = index;
+ break;
+
+ case CTRL_EXTENDED:
+ /* Not Implemented */
+ break;
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info("Control: ID: 0x%x; Type: %u; min: %d; Max: %d; Def: %d; Step: %u\n",
+ mcu_cam_ctrl[index].ctrl_id,
+ mcu_cam_ctrl[index].ctrl_type,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_min,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_max,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_def,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_step
+ );
+#endif
+
+ ctrldb[index] = mcu_cam_ctrl[index].ctrl_id;
+
+ /*
+ * Keep the control list and control db sorted.
+ */
+ while(
+ sorted_elem >= 0 &&
+ (
+ mcu_cam_ctrl[sorted_elem].ctrl_id >
+ mcu_cam_ctrl[elem].ctrl_id
+ )
+ )
+ {
+ ISP_CTRL_INFO swap_ctrl_elem;
+ uint32_t swap_ctrldb_elem;
+
+ /*
+ * Swap the elements in the mcu_cam_ctrl list
+ */
+ memcpy(&swap_ctrl_elem, (mcu_cam_ctrl + sorted_elem), sizeof(ISP_CTRL_INFO));
+ memcpy((mcu_cam_ctrl + sorted_elem), (mcu_cam_ctrl + elem), sizeof(ISP_CTRL_INFO));
+ memcpy((mcu_cam_ctrl + elem), &swap_ctrl_elem, sizeof(ISP_CTRL_INFO));
+
+ /*
+ * Swap the elements in ctrldb
+ */
+ swap_ctrldb_elem = ctrldb[sorted_elem];
+ ctrldb[sorted_elem] = ctrldb[elem];
+ ctrldb[elem] = swap_ctrldb_elem;
+
+ elem = sorted_elem;
+ sorted_elem = elem - 1;
+ }
+ }
+ index++;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+static int mcu_count_or_list_fmts(struct i2c_client *client, ISP_STREAM_INFO *stream_info, int *frm_fmt_size)
+{
+ uint32_t payload_len = 0, err = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0, skip = 0;
+ uint16_t index = 0, mode = 0;
+
+ int loop = 0, num_frates = 0, ret = 0;
+
+ /* Stream Info Variables */
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ /* List all formats from MCU and append to mcu_ar0521_frmfmt array */
+
+ for (index = 0;; index++) {
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_STREAM_INFO;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_STREAM_INFO;
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+ err = ar0521_write(client, mc_data, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (((mc_ret_data[2] << 8) | mc_ret_data[3]) == 0) {
+ if(stream_info == NULL) {
+ *frm_fmt_size = index;
+ } else {
+ *frm_fmt_size = mode;
+ }
+ break;
+ }
+
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) +
+ HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data[2],
+ payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+ if(stream_info != NULL) {
+ stream_info->fmt_fourcc =
+ mc_ret_data[2] << 24 | mc_ret_data[3] << 16 | mc_ret_data[4]
+ << 8 | mc_ret_data[5];
+ stream_info->width = mc_ret_data[6] << 8 | mc_ret_data[7];
+ stream_info->height = mc_ret_data[8] << 8 | mc_ret_data[9];
+ stream_info->frame_rate_type = mc_ret_data[10];
+
+ switch (stream_info->frame_rate_type) {
+ case FRAME_RATE_DISCRETE:
+ stream_info->frame_rate.disc.frame_rate_num =
+ mc_ret_data[11] << 8 | mc_ret_data[12];
+
+ stream_info->frame_rate.disc.frame_rate_denom =
+ mc_ret_data[13] << 8 | mc_ret_data[14];
+
+ break;
+
+ case FRAME_RATE_CONTINOUS:
+ dev_err(&client->dev,
+ " The Stream format at index 0x%04x has FRAME_RATE_CONTINOUS,"
+ "which is unsupported !! \n", index);
+
+ continue;
+ }
+
+ switch (stream_info->fmt_fourcc) {
+ /*
+ * We check for UYVY here instead of YUYV as the output from the sensor
+ * is UYVY. We swap it to YUYV only making changes in the platform driver.
+ */
+ case V4L2_PIX_FMT_UYVY:
+ /* ar0521_codes is already populated with V4L2_PIX_FMT_YUYV */
+ /* check if width and height are already in array - update frame rate only */
+ for (loop = 0; loop < (mode); loop++) {
+ if ((ar0521_data.mcu_cam_frmfmt[loop].size.width ==
+ stream_info->width)
+ && (ar0521_data.mcu_cam_frmfmt[loop].size.height ==
+ stream_info->height)) {
+
+ num_frates =
+ ar0521_data.mcu_cam_frmfmt[loop].num_framerates;
+ *((int *)(ar0521_data.mcu_cam_frmfmt[loop].framerates) + num_frates)
+ = (int)(stream_info->frame_rate.
+ disc.frame_rate_num /
+ stream_info->frame_rate.
+ disc.frame_rate_denom);
+
+ ar0521_data.mcu_cam_frmfmt[loop].num_framerates++;
+
+ streamdb[index] = loop;
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip) {
+ skip = 0;
+ continue;
+ }
+
+ /* Add Width, Height, Frame Rate array, Mode into mcu_ar0521_frmfmt array */
+ ar0521_data.mcu_cam_frmfmt[mode].size.width = stream_info->width;
+ ar0521_data.mcu_cam_frmfmt[mode].size.height = stream_info->height;
+
+ num_frates = ar0521_data.mcu_cam_frmfmt[mode].num_framerates;
+
+ *(ar0521_data.mcu_cam_frmfmt[mode].framerates + num_frates) =
+ (int)(stream_info->frame_rate.disc.frame_rate_num /
+ stream_info->frame_rate.disc.frame_rate_denom);
+
+ ar0521_data.mcu_cam_frmfmt[mode].num_framerates++;
+
+ ar0521_data.mcu_cam_frmfmt[mode].mode = mode;
+ ar0521_data.mcu_cam_frmfmt[mode].mode = mode;
+ streamdb[index] = mode;
+ mode++;
+ break;
+
+ default:
+ dev_err(&client->dev,
+ " The Stream format at index 0x%04x has format 0x%08x ,"
+ "which is unsupported !! \n", index,
+ stream_info->fmt_fourcc);
+ }
+ }
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+/*
+ * Function to initialise the data related to MCU. Needs to be called
+ * before trying to use them.
+ */
+static int mcu_data_init(struct device *dev, int frm_fmt_size)
+{
+ int loop = 0;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ mcu_ctrl_info = devm_kzalloc(dev, sizeof(ISP_CTRL_INFO) * num_ctrls, GFP_KERNEL);
+ if(!mcu_ctrl_info) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ ctrldb = devm_kzalloc(dev, sizeof(uint32_t) * num_ctrls, GFP_KERNEL);
+ if(!ctrldb) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ stream_info = devm_kzalloc(dev, sizeof(ISP_STREAM_INFO) * (frm_fmt_size + 1), GFP_KERNEL);
+
+ streamdb = devm_kzalloc(dev, sizeof(int) * (frm_fmt_size + 1), GFP_KERNEL);
+ if(!streamdb) {
+ dev_err(dev,"Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ ar0521_data.mcu_cam_frmfmt = devm_kzalloc(dev, sizeof(struct mcu_frmfmt) * (frm_fmt_size), GFP_KERNEL);
+ if(!ar0521_data.mcu_cam_frmfmt) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ for(; loop < frm_fmt_size; loop++) {
+ ar0521_data.mcu_cam_frmfmt[loop].framerates = devm_kzalloc(dev, sizeof(int) * MAX_NUM_FRATES, GFP_KERNEL);
+ if(!ar0521_data.mcu_cam_frmfmt[loop].framerates) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static int mcu_get_sensor_id(struct i2c_client *client, uint16_t * sensor_id)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+
+ int ret = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ /* Read the version info. from Micro controller */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_SENSOR_ID;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_SENSOR_ID;
+ err = ar0521_write(client, mc_data, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) + HEADER_FOOTER_SIZE;
+
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ *sensor_id = mc_ret_data[2] << 8 | mc_ret_data[3];
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+static int mcu_get_cmd_status(struct i2c_client *client,
+ uint8_t * cmd_id, uint16_t * cmd_status,
+ uint8_t * ret_code)
+{
+ uint32_t payload_len = 0;
+ uint8_t orig_crc = 0, calc_crc = 0;
+ int err = 0;
+
+ /* No Semaphore in Get command Status */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 1;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_STATUS;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_STATUS;
+ mc_data[2] = *cmd_id;
+ err = ar0521_write(client, mc_data, 3);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ payload_len = CMD_STATUS_MSG_LEN;
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data[2], 3);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ return -EINVAL;
+ }
+
+ *cmd_id = mc_ret_data[2];
+ *cmd_status = mc_ret_data[3] << 8 | mc_ret_data[4];
+ *ret_code = mc_ret_data[payload_len - 1];
+
+ return 0;
+}
+
+static int mcu_isp_init(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /* check current status - if initialized, no need for Init */
+ cmd_id = CMD_ID_INIT_CAM;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n", __func__, __LINE__);
+ return -EIO;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+
+#ifdef AR0521_DEBUG
+ pr_info(" Already Initialized !! \n");
+#endif
+
+ return 0;
+ }
+
+ /* call ISP init command */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_INIT_CAM;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_INIT_CAM;
+ err = ar0521_write(client, mc_data, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ while (--retry > 0) {
+ /* Some Sleep for init to process */
+ mdelay(5);
+
+ cmd_id = CMD_ID_INIT_CAM;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n",
+ __func__, __LINE__);
+ return -EIO;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ ((retcode == ERRCODE_SUCCESS) || (retcode == ERRCODE_ALREADY))) {
+
+#ifdef AR0521_DEBUG
+ pr_info(" ISP Already Initialized !! \n");
+#endif
+
+ return 0;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Init Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ return -EIO;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int mcu_get_ctrl_ui(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ui_info, int index)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ int ret = 0, i = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL_UI_INFO;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL_UI_INFO;
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+ err = ar0521_write(client, mc_data, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) + HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data[2], payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ strncpy((char *)mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_name, &mc_ret_data[2],MAX_CTRL_UI_STRING_LEN);
+
+ mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_type = mc_ret_data[34];
+ mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags = mc_ret_data[35] << 8 |
+ mc_ret_data[36];
+
+ if (mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_type == V4L2_CTRL_TYPE_MENU) {
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem = mc_ret_data[37];
+
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu =
+ devm_kzalloc(&client->dev,((mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem +1) * sizeof(char *)), GFP_KERNEL);
+ for (i = 0; i < mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem; i++) {
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i] =
+ devm_kzalloc(&client->dev,MAX_CTRL_UI_STRING_LEN, GFP_KERNEL);
+ strncpy((char *)mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i],
+ &mc_ret_data[38 +(i *MAX_CTRL_UI_STRING_LEN)], MAX_CTRL_UI_STRING_LEN);
+
+#ifdef AR0521_DEBUG
+ pr_info(" Menu Element %d : %s \n",
+ i, mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i]);
+#endif
+
+ }
+
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i] = NULL;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+
+}
+
+static int mcu_isp_configuration(uint8_t cmd_id,struct i2c_client *client)
+{
+ unsigned char mc_data[100];
+ uint32_t payload_len = 0;
+
+ uint16_t payload_data;
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = cmd_id;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = cmd_id;
+
+ switch(cmd_id) {
+ case CMD_ID_LANE_CONFIG:
+ /*Lane configuration */
+ payload_data = ar0521_data.mipi_lane_config == 4 ? NUM_LANES_4: NUM_LANES_2;
+ mc_data[2] = payload_data >> 8;
+ mc_data[3] = payload_data & 0xFF;
+ break;
+ case CMD_ID_MIPI_CLK_CONFIG:
+ /* MIPI CLK Configuration */
+ payload_data = ar0521_data.mipi_clk_config;
+ mc_data[2] = payload_data >> 8;
+ mc_data[3] = payload_data & 0xFF;
+ break;
+ default:
+ dev_err(&client->dev, "MCU ISP CONF Error\n");
+ err = -1;
+ goto exit;
+ }
+
+ /* CRC*/
+ mc_data[4] = errorcheck(&mc_data[2], payload_len);
+ err = ar0521_write(client, mc_data, payload_len+3);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+
+ while (--retry > 0) {
+ msleep(20);
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Error \n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_ISP_UNINIT) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_ISP_UNINIT))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+ return err;
+}
+
+static int mcu_stream_config(struct i2c_client *client, uint32_t format,
+ int mode, int frate_index)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0, index = 0xFFFF;
+ uint8_t retcode = 0, cmd_id = 0;
+ int loop = 0, ret = 0, err = 0, retry = 1000;
+ static uint16_t prev_index = 0xFFFE;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ cmd_id = CMD_ID_STREAM_CONFIG;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n", __func__, __LINE__);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status != MCU_CMD_STATUS_SUCCESS) ||
+ (retcode != ERRCODE_SUCCESS)) {
+ dev_err(&client->dev,
+ " ISP is Unintialized or Busy STATUS = 0x%04x Errcode = 0x%02x !! \n",
+ cmd_status, retcode);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ for (loop = 0;(&streamdb[loop]) != NULL; loop++) {
+ pr_info("streamdb[%d]=%d, mode=%d",loop,streamdb[loop],mode);
+ if (streamdb[loop] == mode) {
+ index = loop + frate_index;
+ break;
+ }
+ }
+
+#ifdef AR0521_DEBUG
+ pr_info(" Index = 0x%04x , format = 0x%08x, width = %hu,"
+ " height = %hu, frate num = %hu \n", index, format,
+ ar0521_data.mcu_cam_frmfmt[mode].size.width,
+ ar0521_data.mcu_cam_frmfmt[mode].size.height,
+ ar0521_data.mcu_cam_frmfmt[mode].framerates[frate_index]);
+#endif
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if(prev_index == index) {
+#ifdef AR0521_DEBUG
+ pr_info("Skipping Previous mode set ... \n");
+#endif
+ ret = 0;
+ goto exit;
+ }
+
+issue_cmd:
+ /* First Txn Payload length = 0 */
+ payload_len = 14;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_STREAM_CONFIG;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_STREAM_CONFIG;
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+
+ /* Format Fourcc - currently only YUYV */
+ mc_data[4] = format >> 24;
+ mc_data[5] = format >> 16;
+ mc_data[6] = format >> 8;
+ mc_data[7] = format & 0xFF;
+
+ /* width */
+ mc_data[8] = ar0521_data.mcu_cam_frmfmt[mode].size.width >> 8;
+ mc_data[9] = ar0521_data.mcu_cam_frmfmt[mode].size.width & 0xFF;
+
+ /* height */
+ mc_data[10] = ar0521_data.mcu_cam_frmfmt[mode].size.height >> 8;
+ mc_data[11] = ar0521_data.mcu_cam_frmfmt[mode].size.height & 0xFF;
+
+ /* frame rate num */
+ mc_data[12] = ar0521_data.mcu_cam_frmfmt[mode].framerates[frate_index] >> 8;
+ mc_data[13] = ar0521_data.mcu_cam_frmfmt[mode].framerates[frate_index] & 0xFF;
+
+ /* frame rate denom */
+ mc_data[14] = 0x00;
+ mc_data[15] = 0x01;
+
+ mc_data[16] = errorcheck(&mc_data[2], 14);
+ err = ar0521_write(client, mc_data, 17);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ cmd_id = CMD_ID_STREAM_CONFIG;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev,
+ " %s(%d) MCU GET CMD Status Error : loop : %d \n",
+ __func__, __LINE__, loop);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+ ret = 0;
+ goto exit;
+ }
+
+ if(retcode == ERRCODE_AGAIN) {
+ /* Issue Command Again if Set */
+ retry = 1000;
+ goto issue_cmd;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Delay after retry */
+ mdelay(10);
+ }
+
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -ETIMEDOUT;
+
+exit:
+ if(!ret)
+ prev_index = index;
+
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+static int mcu_isp_power_down(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_ISP_PDOWN;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_ISP_PDOWN;
+ err = ar0521_write(client, mc_data, 2);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ msleep(20);
+ cmd_id = CMD_ID_ISP_PDOWN;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Get Status Error \n",
+ __func__, __LINE__);
+ err = -EINVAL;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_ISP_PWDN) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status,
+ retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+ return err;
+}
+
+static int mcu_isp_power_wakeup(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_ISP_PUP;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_ISP_PUP;
+ err = ar0521_write(client, mc_data, 2);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ msleep(20);
+ cmd_id = CMD_ID_ISP_PUP;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Error \n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+ return err;
+}
+
+static int mcu_set_ctrl(struct i2c_client *client, uint32_t arg_ctrl_id,
+ uint8_t ctrl_type, int32_t curr_val)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0, index = 0xFFFF;
+ uint8_t retcode = 0, cmd_id = 0;
+ int loop = 0, ret = 0, err = 0;
+ uint32_t ctrl_id = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ ctrl_id = arg_ctrl_id;
+
+ /* call ISP Ctrl config command */
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == ctrl_id) {
+ index = mcu_ctrl_info[loop].mcu_ctrl_index;
+ break;
+ }
+ }
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* First Txn Payload length = 0 */
+ payload_len = 11;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_SET_CTRL;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ /* Second Txn */
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_SET_CTRL;
+
+ /* Index */
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+
+ /* Control ID */
+ mc_data[4] = ctrl_id >> 24;
+ mc_data[5] = ctrl_id >> 16;
+ mc_data[6] = ctrl_id >> 8;
+ mc_data[7] = ctrl_id & 0xFF;
+
+ /* Ctrl Type */
+ mc_data[8] = ctrl_type;
+
+ /* Ctrl Value */
+ mc_data[9] = curr_val >> 24;
+ mc_data[10] = curr_val >> 16;
+ mc_data[11] = curr_val >> 8;
+ mc_data[12] = curr_val & 0xFF;
+
+ /* CRC */
+ mc_data[13] = errorcheck(&mc_data[2], 11);
+
+ err = ar0521_write(client, mc_data, 14);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ while (1) {
+ cmd_id = CMD_ID_SET_CTRL;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n",
+ __func__, __LINE__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+ ret = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d ISP Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ ret = -EIO;
+ goto exit;
+ }
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+static int mcu_get_ctrl(struct i2c_client *client, uint32_t arg_ctrl_id,
+ uint8_t * ctrl_type, int32_t * curr_val)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ uint16_t index = 0xFFFF;
+ int loop = 0, ret = 0, err = 0;
+
+ uint32_t ctrl_id = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex);
+
+ ctrl_id = arg_ctrl_id;
+
+ /* Read the Ctrl Value from Micro controller */
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == ctrl_id) {
+ index = mcu_ctrl_info[loop].mcu_ctrl_index;
+ break;
+ }
+ }
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (
+ mcu_ctrl_info[loop].ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags &
+ V4L2_CTRL_FLAG_WRITE_ONLY
+ ) {
+ ret = -EACCES;
+ goto exit;
+ }
+
+ /* First Txn Payload length = 2 */
+ payload_len = 2;
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL;
+ mc_data[2] = payload_len >> 8;
+ mc_data[3] = payload_len & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+
+ ar0521_write(client, mc_data, TX_LEN_PKT);
+
+ mc_data[0] = CMD_SIGNATURE;
+ mc_data[1] = CMD_ID_GET_CTRL;
+ mc_data[2] = index >> 8;
+ mc_data[3] = index & 0xFF;
+ mc_data[4] = errorcheck(&mc_data[2], 2);
+ err = ar0521_write(client, mc_data, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar0521_read(client, mc_ret_data, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[4];
+ calc_crc = errorcheck(&mc_ret_data[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -1;
+ goto exit;
+ }
+
+ if (((mc_ret_data[2] << 8) | mc_ret_data[3]) == 0) {
+ ret = -EIO;
+ goto exit;
+ }
+
+ errcode = mc_ret_data[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data[2] << 8) | mc_ret_data[3]) + HEADER_FOOTER_SIZE;
+ memset(mc_ret_data, 0x00, payload_len);
+ err = ar0521_read(client, mc_ret_data, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data[2], payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Ctrl type starts from index 6 */
+
+ *ctrl_type = mc_ret_data[6];
+
+ switch (*ctrl_type) {
+ case CTRL_STANDARD:
+ *curr_val =
+ mc_ret_data[7] << 24 | mc_ret_data[8] << 16 | mc_ret_data[9]
+ << 8 | mc_ret_data[10];
+ break;
+
+ case CTRL_EXTENDED:
+ /* Not Implemented */
+ break;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex);
+
+ return ret;
+}
+
+/*
+ * ---------------------------------------------------------
+ * END of MCU realed functions
+ * ---------------------------------------------------------
+ */
+
+static void toggle_gpio(unsigned int gpio, int val)
+{
+ if (gpio_cansleep(gpio)){
+ gpio_direction_output(gpio,val);
+ gpio_set_value_cansleep(gpio, val);
+ } else{
+ gpio_direction_output(gpio,val);
+ gpio_set_value(gpio, val);
+ }
+}
+
+static int ar0521_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
+{
+ uint32_t index = 0;
+ int loop;
+
+ if (sd == NULL || qm == NULL)
+ return -EINVAL;
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == qm->id) {
+ index = loop;
+ break;
+ }
+ }
+
+ if (loop == num_ctrls) {
+ return -EINVAL;
+ }
+
+ if (
+ !(
+ 0 <= qm->index &&
+ qm->index < mcu_ctrl_info[index].ctrl_ui_data.ctrl_menu_info.num_menu_elem
+ )
+ ) {
+ return -EINVAL;
+ }
+
+ /*
+ * Copy the name of the menu.
+ *
+ * We deal only with V4L2_CTRL_TYPE_MENU and not
+ * V4L2_CTRL_TYPE_INTEGER_MENU. So, this should be
+ * enough.
+ */
+ strcpy(qm->name, mcu_ctrl_info[index].ctrl_ui_data.ctrl_menu_info.menu[qm->index]);
+
+ /*
+ * Set the reserved to zero as mentioned in spec
+ */
+ qm->reserved = 0;
+
+ return 0;
+}
+
+static int ar0521_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ int index, ctrl_index = -1, ctrl_id;
+ bool next_ctrl = (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL);
+
+ if (sd == NULL || qc == NULL)
+ return -EINVAL;
+
+ if (next_ctrl) {
+ ctrl_id = qc->id & (~V4L2_CTRL_FLAG_NEXT_CTRL);
+
+ /*
+ * Ignore the V4L2_CTRL_FLAG_NEXT_COMPOUND for now
+ */
+ ctrl_id = ctrl_id & (~V4L2_CTRL_FLAG_NEXT_COMPOUND);
+ }
+ else {
+ /*
+ * Assume we've just got the control ID itself
+ * directly.
+ */
+ ctrl_id = qc->id;
+ }
+
+ if (ctrl_id) {
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ctrl_id) {
+ ctrl_index = (next_ctrl) ? index + 1 : index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ /*
+ * We do not know about this control
+ */
+ return -EINVAL;
+ }
+ else if (
+ next_ctrl &&
+ index == num_ctrls - 1
+ )
+ {
+ /*
+ * We've got a request for the control
+ * after the last one.
+ */
+ return -EINVAL;
+ }
+ }
+ else if (next_ctrl) {
+ ctrl_index = 0;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ if (
+ mcu_ctrl_info[ctrl_index].ctrl_type == CTRL_STANDARD
+ ) {
+ /*
+ * We cannot use `v4l2_ctrl_query_fill` instead of manually filling
+ * the details even for standard controls as we sometimes implement our
+ * own version for some controls.
+ *
+ * e.g., V4L2_CID_FOCUS_AUTO has a max value of 1 according to standard
+ * but our version of it has a max value of 5.
+ */
+ qc->id = mcu_ctrl_info[ctrl_index].ctrl_id;
+
+ strcpy(qc->name, mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_name);
+
+ qc->type = mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_ui_type;
+ qc->flags = mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags;
+
+ qc->minimum = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min;
+ qc->maximum = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max;
+ qc->step = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_step;
+ qc->default_value = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_def;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ar0521_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = ar0521_data.i2c_client;
+ int err = 0;
+ uint8_t ctrl_type = 0;
+ int ctrl_val = 0;
+
+ if (sd == NULL || ctrl == NULL)
+ return -EINVAL;
+
+ if ((err = mcu_get_ctrl(client, ctrl->id, &ctrl_type, &ctrl_val)) < 0) {
+ return err;
+ }
+
+ if (ctrl_type == CTRL_STANDARD) {
+ ctrl->value = ctrl_val;
+ } else {
+ /* Not Implemented */
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int ar0521_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = ar0521_data.i2c_client;
+ int err = 0, index, ctrl_index = 0;
+
+ if (sd == NULL || ctrl == NULL)
+ return -EINVAL;
+
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ctrl->id) {
+ ctrl_index = index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ return -EINVAL;
+ }
+
+ if (
+ ctrl->value < mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min ||
+ ctrl->value > mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max
+ )
+ return -ERANGE;
+
+ if ((err =
+ mcu_set_ctrl(client, ctrl->id, CTRL_STANDARD, ctrl->value)) < 0) {
+ dev_err(&client->dev," %s (%d ) \n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int ar0521_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i, err = 0;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ struct v4l2_control ctrl = {
+ .id = ext_ctrl->id,
+ };
+
+ err = ar0521_g_ctrl(sd, &ctrl);
+ if (err) {
+ ctrls->error_idx = ctrls->count;
+ break;
+ }
+ else {
+ ext_ctrl->value = ctrl.value;
+ }
+ }
+
+ return err;
+}
+
+static int ar0521_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ int ctrl_index = 0, index;
+
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ext_ctrl->id) {
+ ctrl_index = index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ ctrls->error_idx = ext_ctrl->id;
+ return -EINVAL;
+ }
+
+ if (
+ ext_ctrl->value < mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min ||
+ ext_ctrl->value > mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max
+ ) {
+ ctrls->error_idx = ext_ctrl->id;
+ return -ERANGE;
+ }
+ }
+
+ return 0;
+
+}
+
+static int ar0521_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i, err = 0;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ struct v4l2_control ctrl = {
+ .id = ext_ctrl->id,
+ .value = ext_ctrl->value
+ };
+
+ err = ar0521_s_ctrl(sd, &ctrl);
+ if (err) {
+ /*
+ * TODO: We would have to indicate whether there
+ * is an issue in validation or in the
+ * hardware by correctly setting the error_idx
+ * to count only when the validation failed
+ * and setting it to index when there is an
+ * issue in communication with the hardware.
+ *
+ * For now, just return the count for all cases.
+ */
+ ctrls->error_idx = ctrls->count;
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int ar0521_enum_frameintervals(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_interval_enum *fival)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int j;
+
+ if (fival->width == 0 || fival->height == 0)
+ {
+ dev_err(&client->dev, "Please assign width and height.\n");
+ return -EINVAL;
+ }
+
+ if (fival->code != ar0521_data.fmt.code)
+ {
+ return -EINVAL;
+ }
+
+ for (j = 0; j < ar0521_data.num_frm_fmts; j++) {
+ if (
+ fival->width == ar0521_data.mcu_cam_frmfmt[j].size.width &&
+ fival->height == ar0521_data.mcu_cam_frmfmt[j].size.height
+ ) {
+ if (fival->index >= ar0521_data.mcu_cam_frmfmt[j].num_framerates)
+ {
+ return -EINVAL;
+ }
+
+ fival->interval.numerator = 1;
+ fival->interval.denominator = ar0521_data.mcu_cam_frmfmt[j].framerates[fival->index];
+
+ return 0;
+ }
+ }
+ return -EINVAL;
+
+}
+
+static int ar0521_enum_framesizes(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ar0521_data.num_frm_fmts)
+ {
+ return -EINVAL;
+ }
+
+ if (fse->code != ar0521_data.fmt.code)
+ {
+ return -EINVAL;
+ }
+
+ fse->max_width = ar0521_data.mcu_cam_frmfmt[fse->index].size.width;
+ fse->min_width = fse->max_width;
+
+ fse->max_height = ar0521_data.mcu_cam_frmfmt[fse->index].size.height;
+ fse->min_height = fse->max_height;
+
+ return 0;
+}
+
+static int ar0521_enum_mbus_code(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= AR0521_MAX_FORMAT_SUPPORTED)
+ return -EINVAL;
+
+ code->code = ar0521_data.fmt.code;
+
+ return 0;
+}
+
+static int ar0521_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ if (!enable) {
+ /* Perform Stream Off Sequence - if any */
+ }
+
+ /* Perform Stream On Sequence - if any */
+ mdelay(10);
+
+ return 0;
+}
+
+static int ar0521_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+ int mode = ar0521_data.streamcap.capturemode;
+
+ param->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
+
+ param->parm.capture.timeperframe.denominator =
+ ar0521_data.mcu_cam_frmfmt[mode].framerates[ar0521_data.frate_index];
+ param->parm.capture.timeperframe.numerator = 1;
+
+ return 0;
+}
+
+static int ar0521_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = 0, err = 0;
+ int mode = ar0521_data.streamcap.capturemode;
+ int fourcc = ar0521_data.pix.pixelformat;
+
+ param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ memset(param->parm.capture.reserved, 0, 4*sizeof(u32));
+
+ if (
+ param->parm.capture.timeperframe.denominator == 0 &&
+ param->parm.capture.timeperframe.numerator == 0 &&
+ ar0521_data.mcu_cam_frmfmt[mode].num_framerates == 1
+ ) {
+ param->parm.capture.timeperframe.denominator =
+ ar0521_data.mcu_cam_frmfmt[mode].framerates[ar0521_data.frate_index];
+ param->parm.capture.timeperframe.numerator = 1;
+ /*
+ * We would have to reset the frame interval to a
+ * nominal value in this case but as we just have one
+ * frame interval we just return success.
+ */
+ return 0;
+ }
+
+ if (param->parm.capture.timeperframe.numerator != 1) {
+ dev_err(&client->dev, "Invalid numerator for timeperframe\n");
+ return -EINVAL;
+ }
+
+ for (ret = 0; ret < ar0521_data.mcu_cam_frmfmt[mode].num_framerates;
+ ret++) {
+ if ((ar0521_data.mcu_cam_frmfmt[mode].framerates[ret] ==
+ param->parm.capture.timeperframe.denominator)) {
+ ar0521_data.frate_index = ret;
+
+ /* call stream config with width, height, frame rate */
+ err =
+ mcu_stream_config(client, fourcc, mode,
+ ar0521_data.frate_index);
+ if (err < 0) {
+ dev_err(&client->dev, "%s: Failed stream_config \n", __func__);
+ return err;
+ }
+
+ mdelay(10);
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ar0521_s_power(struct v4l2_subdev *sd, int on)
+{
+
+ /* Perform Power On/Off Sequence - if any */
+ return 0;
+}
+
+static int ar0521_get_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *format)
+{
+ int ret = 0;
+
+ if (format->pad)
+ return -EINVAL;
+
+ format->format.code = ar0521_data.fmt.code;
+ format->format.colorspace = ar0521_data.fmt.colorspace;
+ format->format.field = V4L2_FIELD_NONE;
+
+ format->format.width = ar0521_data.pix.width;
+ format->format.height = ar0521_data.pix.height;
+
+ return ret;
+}
+
+static int ar0521_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ int ret = 0, i;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int flag = 0, err = 0;
+
+ format->format.code = ar0521_data.fmt.code;
+ format->format.colorspace = ar0521_data.fmt.colorspace;
+ format->format.field = V4L2_FIELD_NONE;
+
+ for (i = 0; i < ar0521_data.num_frm_fmts ; i++) {
+ if (
+ ar0521_data.mcu_cam_frmfmt[i].size.width == format->format.width &&
+ ar0521_data.mcu_cam_frmfmt[i].size.height == format->format.height
+ ) {
+ flag = 1;
+ break;
+ }
+ }
+
+ if(flag == 0) {
+ format->format.width = ar0521_data.pix.width;
+ format->format.height = ar0521_data.pix.height;
+ }
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ {
+ return 0;
+ }
+
+ /* call stream config with width, height, frame rate */
+ err =
+ mcu_stream_config(client, ar0521_data.pix.pixelformat, ar0521_data.mcu_cam_frmfmt[i].mode,
+ ar0521_data.frate_index);
+ if (err < 0) {
+ dev_err(&client->dev, "%s: Failed stream_config \n", __func__);
+ return err;
+ }
+
+ ar0521_data.pix.width = format->format.width;
+ ar0521_data.pix.height = format->format.height;
+ ar0521_data.streamcap.capturemode = ar0521_data.mcu_cam_frmfmt[i].mode;
+
+ mdelay(10);
+
+ return ret;
+}
+
+static int ar0521_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ar0521_subdev_video_ops = {
+ .g_parm = ar0521_g_parm,
+ .s_parm = ar0521_s_parm,
+ .s_stream = ar0521_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ar0521_subdev_pad_ops = {
+ .enum_frame_size = ar0521_enum_framesizes,
+ .enum_frame_interval = ar0521_enum_frameintervals,
+ .enum_mbus_code = ar0521_enum_mbus_code,
+ .set_fmt = ar0521_set_fmt,
+ .get_fmt = ar0521_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ar0521_subdev_core_ops = {
+ .s_power = ar0521_s_power,
+ .queryctrl = ar0521_queryctrl,
+ .g_ctrl = ar0521_g_ctrl,
+ .s_ctrl = ar0521_s_ctrl,
+ .g_ext_ctrls = ar0521_g_ext_ctrls,
+ .s_ext_ctrls = ar0521_s_ext_ctrls,
+ .try_ext_ctrls = ar0521_try_ext_ctrls,
+ .querymenu = ar0521_querymenu,
+};
+
+static struct v4l2_subdev_ops ar0521_subdev_ops = {
+ .core = &ar0521_subdev_core_ops,
+ .video = &ar0521_subdev_video_ops,
+ .pad = &ar0521_subdev_pad_ops,
+};
+
+static const struct media_entity_operations ar0521_sd_media_ops = {
+ .link_setup = ar0521_link_setup,
+};
+
+static int ar0521_init(struct i2c_client *client)
+{
+ u32 tgt_xclk; /* target xclk */
+ int ret = 0;
+
+ ar0521_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ar0521_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)AR0521_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)AR0521_XCLK_MIN);
+ ar0521_data.mclk = tgt_xclk;
+
+#ifdef AR0521_DEBUG
+ pr_info("mclk: %d MHz\n", tgt_xclk / 1000000);
+#endif
+
+ ret = mcu_stream_config(client, ar0521_data.pix.pixelformat,
+ ar0521_data.streamcap.capturemode,
+ ar0521_data.frate_index);
+
+ return ret;
+}
+
+static int ar0521_ctrls_init(ISP_CTRL_INFO *mcu_cam_ctrls)
+{
+ struct i2c_client *client = NULL;
+ int numctrls = 0;
+ int err = 0, i = 0;
+
+ client = ar0521_data.i2c_client;
+
+ if (mcu_cam_ctrls == NULL)
+ {
+ dev_err(
+ &client->dev,
+ "%s: MCU control data hasn't been allocated\n",
+ __func__
+ );
+ return -EINVAL;
+ }
+ /*
+ * Enumerate the controls from the MCU
+ */
+ err = mcu_count_or_list_ctrls(client, mcu_cam_ctrls, &numctrls);
+ if (err < 0) {
+ dev_err(&client->dev, "Unable to enumerate the controls in the sensor\n");
+ return err;
+ }
+
+ for (i = 0; i < numctrls; i++) {
+ if (mcu_cam_ctrls[i].ctrl_type == CTRL_STANDARD) {
+ err = mcu_get_ctrl_ui(client, &mcu_ctrl_info[i], mcu_ctrl_info[i].mcu_ctrl_index);
+ if (err != ERRCODE_SUCCESS) {
+ dev_err(&client->dev, "Error Enumerating Control 0x%08x !! \n",
+ mcu_ctrl_info[i].ctrl_id);
+ return err;
+ }
+ else if (
+ mcu_ctrl_info[i].ctrl_ui_data.ctrl_ui_info.ctrl_ui_type ==
+ V4L2_CTRL_TYPE_MENU
+ ) {
+ mcu_ctrl_info[i].ctrl_data.std.ctrl_step = 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int ar0521_verify_mcu(struct i2c_client *client)
+{
+ int ret = 0, try = 0;
+ unsigned char fw_version[32] = {0};
+
+ if (client == NULL)
+ {
+ dev_err(&client->dev, "%s: Invalid I2C client parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Try to boot the MCU into firmware mode.
+ *
+ * We do this only when the reset_gpio and pwdn_gpio are
+ * available.
+ */
+ if (gpios_available())
+ {
+ toggle_gpio(pwdn_gpio, 0);
+ msleep(10);
+ toggle_gpio(reset_gpio, 0);
+ msleep(10);
+ toggle_gpio(reset_gpio, 1);
+ msleep(500);
+
+ for(try = 0; try < 10; try++) {
+ ret = mcu_get_fw_version(client, fw_version);
+ if(ret < 0) {
+ msleep(100);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version);
+ }
+ else
+ {
+ dev_dbg(
+ &client->dev,
+ "Could not read the firmware version from the MCU\n"
+ );
+ pr_info(" Could not read the firmware version from the MCU, tries=%d\n", try+1);
+ }
+
+ /*
+ * Try booting and flashing in bootloader mode when an error is detected
+ * or the force update bit is set in the firmware version
+ */
+ if (ret != 0) {
+ int loop = 0;
+
+ /*
+ * Verification of the MCU in firmware mode failed so
+ * try to boot the MCU in bootloader mode.
+ */
+
+ pr_info(" Trying to Detect Bootloader mode\n");
+
+ if (gpios_available())
+ {
+ toggle_gpio(reset_gpio, 0);
+ msleep(10);
+ toggle_gpio(pwdn_gpio, 1);
+ msleep(100);
+ toggle_gpio(reset_gpio, 1);
+ msleep(100);
+ }
+
+ for(loop = 0; loop < 10; loop++) {
+ ret = mcu_bload_get_version(client);
+ if (ret < 0) {
+ /* Trial and Error for 1 second (100ms * 10) */
+ msleep(100);
+ continue;
+ } else {
+#ifdef AR0521_DEBUG
+ pr_info(" Get Bload Version Success\n");
+#endif
+ break;
+ }
+ }
+
+ if(loop == 10) {
+ dev_err(&client->dev, "Error getting firmware version in bootloader mode\n");
+ return -EINVAL;
+ }
+
+ if (mcu_fw_update(client, NULL) < 0) {
+ dev_err(&client->dev, "Error when trying to update the firmware\n");
+ return -EFAULT;
+ }
+
+ if (gpios_available())
+ {
+ toggle_gpio(pwdn_gpio, 0);
+ }
+
+ /* Allow FW Updated MCU to reboot */
+ msleep(500);
+
+ /*
+ * Ensure the firmware has been flashed correctly by getting the version
+ * of the firmware (in firmware mode).
+ */
+ for(loop = 0; loop < 100; loop++) {
+ ret = mcu_get_fw_version(client, fw_version);
+
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version);
+ }
+
+ if (ret < 0) {
+ /* Trial and Error for 10 seconds (100ms * 100) */
+ msleep(100);
+ continue;
+ } else {
+#ifdef AR0521_DEBUG
+ pr_info(" Get FW Version Success\n");
+#endif
+ break;
+ }
+ }
+
+ if(loop == 100) {
+ dev_err(
+ &client->dev,
+ "Couldn't get firmware version correctly after update (did the update fail?\n"
+ );
+ return -EINVAL;
+ }
+ }
+
+ }
+ else
+ {
+ static const char *const flash_error_message =
+ "Please connect only one camera and fix the MCU.\n"
+ "Hint: Connected only one camera? Is someone else using the "
+ "power down/reset GPIOs?\n";
+
+ /*
+ * When we do not have the reset GPIO, we cannot toggle it
+ * to make the MCU switch to firmware mode. So, we try getting
+ * the MCU into firmware assuming it is currently in
+ * bootloader mode.
+ *
+ * The following sequence is required for switching it to
+ * firmware mode.
+ */
+ int loop, get_firmware_version = 0;
+
+ /*
+ * We would have to verify that the MCU is in bootloader mode
+ * before sending the command to make it switch to firmware mode.
+ *
+ * So, we try to get the version of the bootloader.
+ */
+ for(loop = 0; loop < 10; loop++)
+ {
+ ret = mcu_bload_get_version(client);
+ if (ret < 0)
+ {
+ /* Trial and Error for 1 second (100ms * 10) */
+ msleep(100);
+ }
+ else
+ {
+ pr_info(" Get Bload Version Success\n");
+ break;
+ }
+ }
+
+ if(loop == 10)
+ {
+ dev_err(&client->dev, "couldn't get bootloader version\n");
+
+
+ get_firmware_version = 1;
+
+ msleep(1000);
+ }
+ else
+ {
+ /*
+ * We retry if we could boot into firmware mode as we're
+ * currently in bootloader mode (as mcu_bload_get_version
+ * succeeded).
+ */
+ ret = mcu_bload_go(client);
+ if (ret < 0) {
+ dev_err(&client->dev,"couldn't switch to firmware mode.\n");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+ else {
+ msleep(10);
+ get_firmware_version = 1;
+ }
+ }
+
+ /*
+ * We should verify if we have the version of the MCU we
+ * need. If not, we let the user know about it and exit
+ * the probe.
+ */
+ if (get_firmware_version)
+ {
+ ret = mcu_get_fw_version(client, fw_version);
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version);
+ }
+ else
+ {
+ dev_err(&client->dev, "couldn't get the MCU firmware version");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+
+ if (ret != 0)
+ {
+ dev_err(&client->dev, "wrong MCU firmware version");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+ }
+ }
+
+ dev_info(&client->dev, "Current Firmware Version - (%.32s)\n", fw_version);
+
+ return 0;
+}
+
+static int ar0521_parse_and_get_clocks(struct device *dev)
+{
+ int retval = 0;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ ar0521_data.sensor_clk = devm_clk_get(dev, "xclk");
+ if (IS_ERR(ar0521_data.sensor_clk)) {
+ /* assuming clock enabled by default */
+ ar0521_data.sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(ar0521_data.sensor_clk);
+ }
+
+ /*mclk reserved for future use*/
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(ar0521_data.mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ /*mclk_source reserved for future use*/
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ar0521_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ar0521_data.csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ return 0;
+}
+
+static int ar0521_parse_and_get_gpios(struct device *dev)
+{
+ int err;
+ struct device_node *node = NULL;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ node = dev->of_node;
+
+ pwdn_gpio = of_get_named_gpio(node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwdn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available");
+ return -EINVAL;
+ }
+ else {
+#ifdef AR0521_DEBUG
+ printk("BOOT = %x \n", pwdn_gpio);
+#endif
+ }
+
+ reset_gpio = of_get_named_gpio(node, "rst-gpios", 0);
+ if (!gpio_is_valid(reset_gpio)) {
+ dev_err(dev, "no sensor reset pin available");
+ return -EINVAL;
+ }
+ else {
+#ifdef AR0521_DEBUG
+ printk("RESET = %x \n", reset_gpio);
+#endif
+ }
+
+ err = devm_gpio_request_one(dev, pwdn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ar0521_mipi_pwdn");
+ if (err < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ dev_warn(dev, "err = %d\n", err);
+ return err;
+ }
+
+ err = devm_gpio_request_one(dev, reset_gpio, GPIOF_OUT_INIT_HIGH,
+ "ar0521_mipi_reset");
+ if (err < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ dev_warn(dev, "err = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+/*!
+ * ar0521 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ar0521_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device_node *node = client->dev.of_node;
+ struct device *dev = &client->dev;
+
+ int ret, frm_fmt_size = 0, i;
+ uint16_t sensor_id = 0;
+
+ if (!IS_ENABLED(CONFIG_OF) || !node)
+ return -EINVAL;
+
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(dev, "no pin available\n");
+
+ /* Set initial values for the sensor struct. */
+ memset(&ar0521_data, 0, sizeof(ar0521_data));
+
+ ret = ar0521_parse_and_get_gpios(dev);
+ if (ret)
+ {
+ pr_info("Warning: couldn't get GPIOs\n");
+ }
+
+ ret = ar0521_parse_and_get_clocks(dev);
+ if (ret)
+ {
+ dev_err(dev, "Error occurred when getting clock\n");
+ return ret;
+ }
+
+ clk_prepare_enable(ar0521_data.sensor_clk);
+
+ /*
+ * We usually get and set/enable regulators here. But it doesn't
+ * seem to be needed here as the Variscite EVK seems to be supplying
+ * the required voltage directly without us needing to set it.
+ */
+ toggle_gpio(reset_gpio, 1);
+ msleep(500);
+
+ ret = ar0521_verify_mcu(client);
+ if (ret)
+ {
+ dev_err(dev, "Error occurred when verifying MCU\n");
+ return ret;
+ }
+
+ ar0521_data.mipi_lane_config = 4;
+ ret = mcu_isp_configuration(CMD_ID_LANE_CONFIG, client);
+ if(ret)
+ {
+ dev_err(dev, "Error occurred in configuring mipi lanes\n");
+ return ret;
+ }
+
+ /*
+ * Query the number of controls from MCU
+ */
+ if (mcu_count_or_list_ctrls(client, NULL, &num_ctrls) < 0) {
+ dev_err(dev, "%s, Failed to get number of controls for sensor\n", __func__);
+ return -EFAULT;
+ }
+
+ /*
+ * Query the number for Formats available from MCU
+ */
+ if (mcu_count_or_list_fmts(client, NULL, &frm_fmt_size) < 0) {
+ dev_err(dev, "%s, Failed to get number of formats for sensor\n", __func__);
+ return -EFAULT;
+ }
+
+ /*
+ * Initialise the MCU related data as we're about to use them.
+ */
+ ret = mcu_data_init(dev, frm_fmt_size);
+ if (ret)
+ {
+ dev_err(dev, "%s: failed to initialize MCU related data\n", __func__);
+ return -EFAULT;
+ }
+
+ if (mcu_get_sensor_id(client, &sensor_id) < 0) {
+ dev_err(dev, "Unable to get MCU Sensor ID \n");
+ return -EFAULT;
+ }
+
+ if (mcu_isp_init(client) < 0) {
+ dev_err(dev, "Unable to INIT ISP \n");
+ return -EFAULT;
+ }
+
+ /*
+ * Enumerate the Formats in the sensor
+ */
+ if (mcu_count_or_list_fmts(client, stream_info, &frm_fmt_size) < 0) {
+ dev_err(dev, "Unable to enumerate the formats in the sensor\n");
+ return -EFAULT;
+ }
+
+ /*
+ * Fill some state information as required.
+ */
+ ar0521_data.i2c_client = client;
+
+ ar0521_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ ar0521_data.fmt.code = AR0521_DEFAULT_DATAFMT;
+ ar0521_data.fmt.colorspace = AR0521_DEFAULT_COLORSPACE;
+ ar0521_data.pix.width = AR0521_DEFAULT_WIDTH;
+ ar0521_data.pix.height = AR0521_DEFAULT_HEIGHT;
+ ar0521_data.streamcap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
+ ar0521_data.streamcap.capturemode = AR0521_DEFAULT_MODE;
+ ar0521_data.num_frm_fmts = frm_fmt_size;
+ ar0521_data.power_on = 0;
+
+ /*
+ * Configure the stream with default configuration
+ */
+ ret = ar0521_init(client);
+ if (ret)
+ {
+ dev_err(dev, "Failed to initialise the device with default configuration\n");
+ return ret;
+ }
+
+ v4l2_i2c_subdev_init(&ar0521_data.subdev, client, &ar0521_subdev_ops);
+
+ /*
+ * Initialize Controls by getting details about the controls from the MCU
+ */
+ ret = ar0521_ctrls_init(mcu_ctrl_info);
+ if (ret)
+ {
+ dev_warn(dev, "Failed to initialise the controls. Controls might not work\n");
+ }
+
+ /*
+ * Write default values for all controls
+ */
+ for (i = 0; i < num_ctrls; i++) {
+ if (mcu_ctrl_info[i].ctrl_type == CTRL_STANDARD) {
+ int ret;
+ struct v4l2_control ctrl = {
+ .id = mcu_ctrl_info[i].ctrl_id,
+ .value = mcu_ctrl_info[i].ctrl_data.std.ctrl_def
+ };
+
+ if (
+ mcu_ctrl_info[i].ctrl_id == 0x9a0926
+ )
+ {
+ /*
+ * We know that the MCU would fail when we
+ * try to write the V4L2_CID_ROI_EXPOSURE
+ * control as we are not in the correct auto
+ * exposure mode by default. So, skip it.
+ */
+ continue;
+ }
+
+ ret = ar0521_s_ctrl(&ar0521_data.subdev, &ctrl);
+ if (ret < 0)
+ {
+ dev_err(dev, "Failed to write default value for a control: %d; Control ID: %x\n", i, mcu_ctrl_info[i].ctrl_id);
+ }
+ }
+ }
+
+ ar0521_data.subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ar0521_data.subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ar0521_data.pads[0].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&ar0521_data.subdev.entity, 1, ar0521_data.pads);
+ ar0521_data.subdev.entity.ops = &ar0521_sd_media_ops;
+ if (ret < 0) {
+ dev_err(dev, "Failed to init media entity pads\n");
+ return ret;
+ }
+
+ ret = v4l2_async_register_subdev(&ar0521_data.subdev);
+ if (ret)
+ {
+ dev_err(dev, "Failed to register the I2C subdev for the sensor\n");
+ return ret;
+ }
+
+ pr_info("AR0521 detected.\n");
+
+ return 0;
+}
+
+/*!
+ * ar0521 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ar0521_remove(struct i2c_client *client)
+{
+ v4l2_async_unregister_subdev(&ar0521_data.subdev);
+
+ clk_disable_unprepare(ar0521_data.sensor_clk);
+
+ /*
+ * Power down the MCU
+ */
+ if (reset_gpio >= 0)
+ {
+ toggle_gpio(reset_gpio, 0);
+ }
+
+ /*
+ * Free up the GPIOs
+ */
+ if (pwdn_gpio >= 0)
+ devm_gpio_free(&client->dev, pwdn_gpio);
+
+ if (reset_gpio >= 0)
+ devm_gpio_free(&client->dev, reset_gpio);
+
+ return 0;
+}
+
+static const struct i2c_device_id ar0521_id[] = {
+ {"ar0521", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ar0521_id);
+
+static struct i2c_driver ar0521_i2c_driver = {
+ .driver = {
+ .name = "ar0521",
+ .owner = THIS_MODULE
+ },
+ .probe = ar0521_probe,
+ .remove = ar0521_remove,
+ .id_table = ar0521_id,
+};
+
+
+module_i2c_driver(ar0521_i2c_driver);
+
+MODULE_DESCRIPTION("AR0521 V4L2 driver");
+MODULE_AUTHOR("e-con Systems");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/imx8/ar0521.h b/drivers/media/platform/imx8/ar0521.h
new file mode 100644
index 000000000000..05bdb30bbb4f
--- /dev/null
+++ b/drivers/media/platform/imx8/ar0521.h
@@ -0,0 +1,291 @@
+/*
+ * ar0521.h - ar0521 sensor mode tables
+ *
+ * Copyright (c) 2018-2019, e-con Systems, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 __AR0521_TABLES__
+#define __AR0521_TABLES__
+
+#define AR0521_XCLK_MIN 6000000
+#define AR0521_XCLK_MAX 24000000
+
+#define ar0521_reg struct reg_16
+#define AR0521_TABLE_WAIT_MS 0
+#define AR0521_TABLE_END 1
+#define AR0521_WAIT_MS 10
+#define AR0521_DEFAULT_MODE 0
+
+#define AR0521_DEFAULT_WIDTH 640
+#define AR0521_DEFAULT_HEIGHT 480
+
+#define AR0521_MAX_FORMAT_SUPPORTED 1
+
+#define AR0521_DEFAULT_FPS 120
+
+#define AR0521_DEFAULT_DATAFMT MEDIA_BUS_FMT_UYVY8_2X8
+#define AR0521_DEFAULT_COLORSPACE V4L2_COLORSPACE_SRGB
+
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
+/* Defines related to MCU */
+
+#define CMD_SIGNATURE 0x43
+#define TX_LEN_PKT 5
+#define RX_LEN_PKT 6
+#define HEADER_FOOTER_SIZE 4
+#define CMD_STATUS_MSG_LEN 7
+
+#define VERSION_SIZE 32
+#define VERSION_FILE_OFFSET 100
+
+#define MCU_CMD_STATUS_SUCCESS 0x0000
+#define MCU_CMD_STATUS_PENDING 0xF000
+#define MCU_CMD_STATUS_ISP_PWDN 0x0FF0
+#define MCU_CMD_STATUS_ISP_UNINIT 0x0FF1
+
+#define MAX_NUM_FRATES 10
+#define MAX_CTRL_DATA_LEN 100
+#define MAX_CTRL_UI_STRING_LEN 32
+
+typedef enum _errno {
+ ERRCODE_SUCCESS = 0x00,
+ ERRCODE_BUSY = 0x01,
+ ERRCODE_INVAL = 0x02,
+ ERRCODE_PERM = 0x03,
+ ERRCODE_NODEV = 0x04,
+ ERRCODE_IO = 0x05,
+ ERRCODE_HW_SPEC = 0x06,
+ ERRCODE_AGAIN = 0x07,
+ ERRCODE_ALREADY = 0x08,
+ ERRCODE_NOTIMPL = 0x09,
+ ERRCODE_RANGE = 0x0A,
+
+ /* Reserved 0x0B - 0xFE */
+
+ ERRCODE_UNKNOWN = 0xFF,
+} RETCODE;
+
+typedef enum _cmd_id {
+ CMD_ID_VERSION = 0x00,
+ CMD_ID_GET_SENSOR_ID = 0x01,
+ CMD_ID_GET_STREAM_INFO = 0x02,
+ CMD_ID_GET_CTRL_INFO = 0x03,
+ CMD_ID_INIT_CAM = 0x04,
+ CMD_ID_GET_STATUS = 0x05,
+ CMD_ID_DE_INIT_CAM = 0x06,
+ CMD_ID_STREAM_ON = 0x07,
+ CMD_ID_STREAM_OFF = 0x08,
+ CMD_ID_STREAM_CONFIG = 0x09,
+ CMD_ID_GET_CTRL_UI_INFO = 0x0A,
+
+ /* Reserved 0x0B to 0x0F */
+
+ CMD_ID_GET_CTRL = 0x10,
+ CMD_ID_SET_CTRL = 0x11,
+
+ /* Reserved 0x12, 0x13 */
+
+ CMD_ID_FW_UPDT = 0x14,
+ CMD_ID_ISP_PDOWN = 0x15,
+ CMD_ID_ISP_PUP = 0x16,
+
+ /* Reserved - 0x17 to 0xFE (except 0x43) */
+ CMD_ID_LANE_CONFIG = 0x17,
+ CMD_ID_MIPI_CLK_CONFIG = 0x18,
+
+ CMD_ID_UNKNOWN = 0xFF,
+
+} HOST_CMD_ID;
+
+enum {
+ FRAME_RATE_DISCRETE = 0x01,
+ FRAME_RATE_CONTINOUS = 0x02,
+};
+
+enum {
+ CTRL_STANDARD = 0x01,
+ CTRL_EXTENDED = 0x02,
+};
+
+enum {
+/* 0x01 - Integer (32bit)
+ 0x02 - Long Int (64 bit)
+ 0x03 - String
+ 0x04 - Pointer to a 1-Byte Array
+ 0x05 - Pointer to a 2-Byte Array
+ 0x06 - Pointer to a 4-Byte Array
+ 0x07 - Pointer to Generic Data (custom Array)
+*/
+
+ EXT_CTRL_TYPE_INTEGER = 0x01,
+ EXT_CTRL_TYPE_LONG = 0x02,
+ EXT_CTRL_TYPE_STRING = 0x03,
+ EXT_CTRL_TYPE_PTR8 = 0x04,
+ EXT_CTRL_TYPE_PTR16 = 0x05,
+ EXT_CTRL_TYPE_PTR32 = 0x06,
+ EXT_CTRL_TYPE_VOID = 0x07,
+};
+
+/* Stream and Control Info Struct */
+typedef struct _isp_stream_info {
+ uint32_t fmt_fourcc;
+ uint16_t width;
+ uint16_t height;
+ uint8_t frame_rate_type;
+ union {
+ struct {
+ uint16_t frame_rate_num;
+ uint16_t frame_rate_denom;
+ } disc;
+ struct {
+ uint16_t frame_rate_min_num;
+ uint16_t frame_rate_min_denom;
+ uint16_t frame_rate_max_num;
+ uint16_t frame_rate_max_denom;
+ uint16_t frame_rate_step_num;
+ uint16_t frame_rate_step_denom;
+ } cont;
+ } frame_rate;
+} ISP_STREAM_INFO;
+
+
+typedef struct _isp_ctrl_ui_info {
+ struct {
+ char ctrl_name[MAX_CTRL_UI_STRING_LEN];
+ uint8_t ctrl_ui_type;
+ uint8_t ctrl_ui_flags;
+ } ctrl_ui_info;
+
+ /* This Struct is valid only if ctrl_ui_type = 0x03 */
+ struct {
+ uint8_t num_menu_elem;
+ char **menu;
+ } ctrl_menu_info;
+} ISP_CTRL_UI_INFO;
+
+typedef struct _isp_ctrl_info_std {
+ uint32_t ctrl_id;
+ uint8_t ctrl_type;
+ uint8_t mcu_ctrl_index;
+ union {
+ struct {
+ int32_t ctrl_min;
+ int32_t ctrl_max;
+ int32_t ctrl_def;
+ int32_t ctrl_step;
+ } std;
+ struct {
+ uint8_t val_type;
+ uint32_t val_length;
+ // This size may vary according to ctrl types
+ uint8_t val_data[MAX_CTRL_DATA_LEN];
+ } ext;
+ } ctrl_data;
+ ISP_CTRL_UI_INFO ctrl_ui_data;
+} ISP_CTRL_INFO;
+
+struct ar0521 {
+ int numctrls;
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ uint16_t frate_index;
+ struct media_pad pads[1];
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+
+ int csi;
+
+ /*
+ * Format related data
+ */
+ struct v4l2_pix_format pix;
+
+ struct ar0521_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+ } fmt;
+
+ struct v4l2_captureparm streamcap;
+
+ bool on;
+
+ int num_frm_fmts;
+
+ /*
+ * Array of Camera framesizes
+ *
+ * Moved from global
+ */
+ struct mcu_frmfmt {
+ struct v4l2_frmsize_discrete size;
+ unsigned int * framerates;
+ int num_framerates;
+ int mode;
+ } *mcu_cam_frmfmt;
+
+ int power_on;
+
+ uint16_t mipi_lane_config;
+ uint16_t mipi_clk_config;
+
+ struct v4l2_ctrl *ctrls[];
+
+};
+
+static ISP_STREAM_INFO *stream_info = NULL;
+static ISP_CTRL_INFO *mcu_ctrl_info = NULL;
+
+/* Total formats */
+static int num_ctrls = 0;
+static int *streamdb;
+static uint32_t *ctrldb;
+
+/* Mutex for I2C lock */
+DEFINE_MUTEX(mcu_i2c_mutex);
+
+static int ar0521_read(struct i2c_client *client, u8 * val, u32 count);
+static int ar0521_write(struct i2c_client *client, u8 * val, u32 count);
+static int ar0521_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
+static int ar0521_s_power(struct v4l2_subdev *sd, int on);
+
+/*
+ * MCU related functions
+ */
+static int mcu_get_fw_version(struct i2c_client *client, unsigned char * fw_version);
+static int mcu_verify_fw_version(const unsigned char *const fw_version);
+static int mcu_count_or_list_fmts(struct i2c_client *client, ISP_STREAM_INFO *stream_info, int *frm_fmt_size);
+static int mcu_count_or_list_ctrls(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ctrl_info, int *numctrls);
+static int mcu_get_sensor_id(struct i2c_client *client, uint16_t * sensor_id);
+static int mcu_get_cmd_status(struct i2c_client *client, uint8_t * cmd_id,
+ uint16_t * cmd_status, uint8_t * ret_code);
+static int mcu_isp_init(struct i2c_client *client);
+static int mcu_stream_config(struct i2c_client *client, uint32_t format,
+ int mode, int frate_index);
+static int mcu_set_ctrl(struct i2c_client *client, uint32_t ctrl_id,
+ uint8_t ctrl_type, int32_t curr_val);
+static int mcu_get_ctrl(struct i2c_client *client, uint32_t ctrl_id,
+ uint8_t * ctrl_type, int32_t * curr_val);
+static int mcu_get_ctrl_ui(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ui_info, int index);
+static int mcu_fw_update(struct i2c_client *client, unsigned char *txt_fw_version);
+static int mcu_isp_power_down(struct i2c_client *client);
+static int mcu_isp_power_wakeup(struct i2c_client *client);
+
+#endif /* __AR0521_TABLES__ */
diff --git a/drivers/media/platform/imx8/ar1335.c b/drivers/media/platform/imx8/ar1335.c
new file mode 100644
index 000000000000..c798bc938263
--- /dev/null
+++ b/drivers/media/platform/imx8/ar1335.c
@@ -0,0 +1,3625 @@
+/*
+ * ar1335.c - AR1335 sensor driver
+ * Copyright (c) 2020-2021, e-con Systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#include "ar1335.h"
+#include "mcu_firmware_1335.h"
+
+/*
+#define AR1335_DEBUG 1
+*/
+
+/*!
+ * Maintains the information on the current state of the sensor.
+ */
+static struct ar1335 ar1335_data;
+
+static int pwdn_gpio, reset_gpio;
+
+int gpios_available_1335(void)
+{
+ return (pwdn_gpio >= 0) && (reset_gpio >= 0);
+}
+
+/**********************************************************************
+ *
+ * START of AR1335 related code
+ *
+ **********************************************************************
+ */
+
+static int ar1335_write(struct i2c_client *client, u8 * val, u32 count)
+{
+ int ret;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = count,
+ .buf = val,
+ };
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed writing register.\n");
+ dev_err(&client->dev, "addr: %x; val = %hhu, ret = %d!\n",
+ client->addr, *val, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ar1335_read(struct i2c_client *client, u8 * val, u32 count)
+{
+ int ret;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = val,
+ };
+
+ msg.flags = I2C_M_RD;
+ msg.len = count;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+ err:
+ dev_err(&client->dev, "Failed reading register ret = %d!\n", ret);
+ return ret;
+}
+
+/*
+ * The MCU specific functions below depend on the sensor-specific
+ * functions above.
+ */
+
+/*
+ * ---------------------------------------------------------
+ * START of MCU realed functions
+ * ---------------------------------------------------------
+ */
+
+/*
+ * NOTE about modularizing this MCU related function.
+ *
+ * - The functions:
+ *
+ * x mcu_get_fw_version
+ * x mcu_bload_get_version
+ * x mcu_bload_erase_flash
+ * x mcu_bload_parse_send_cmd
+ * x mcu_bload_go
+ * x mcu_bload_read
+ * x mcu_count_or_list_ctrls
+ * x mcu_count_or_list_fmts
+ * x mcu_get_sensor_id
+ * x mcu_get_ctrl_ui
+ * x mcu_stream_config
+ * x mcu_isp_power_down
+ * x mcu_isp_power_wakeup
+ * x mcu_set_ctrl
+ * x mcu_get_ctrl
+ *
+ * seem to directly use platform specific functions:
+ *
+ * x ar1335_write
+ * x ar1335_read
+ *
+ * This could be passed in as a function pointer.
+ */
+
+static unsigned short int mcu_bload_calc_crc16(unsigned char *buf, int len)
+{
+ unsigned short int crc = 0;
+ int i = 0;
+
+ if (!buf || !(buf + len))
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ crc ^= buf[i];
+ }
+
+ return crc;
+}
+
+static int mcu_bload_ascii2hex(unsigned char ascii)
+{
+ if (ascii <= '9') {
+ return (ascii - '0');
+ } else if ((ascii >= 'a') && (ascii <= 'f')) {
+ return (0xA + (ascii - 'a'));
+ } else if ((ascii >= 'A') && (ascii <= 'F')) {
+ return (0xA + (ascii - 'A'));
+ }
+ return -1;
+}
+
+static unsigned char errorcheck(char *data, unsigned int len)
+{
+ unsigned int i = 0;
+ unsigned char crc = 0x00;
+
+ for (i = 0; i < len; i++) {
+ crc ^= data[i];
+ }
+
+ return crc;
+}
+
+/*
+ * mcu_get_fw_version:
+ *
+ * Read the firmware version from the MCU.
+ *
+ * A success value (0) is returned when the MCU version could be successfully read.
+ * else a negative value indicating error is returned.
+ */
+static int mcu_get_fw_version(struct i2c_client *client, unsigned char *fw_version_1335)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ int ret = 0, err = 0, loop;
+ /* Query firmware version from MCU */
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_VERSION;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ err = ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+ if (err != 0)
+ {
+ dev_err(&client->dev, "MCU CMD ID version Error- %d\n", err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_VERSION;
+ err = ar1335_write(client, mc_data_1335, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID Write PKT fw Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID Read PKT fw Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID fw Version Error CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) MCU CMD ID fw Errcode - 0x%02x \n", __func__,
+ __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Read the actual version from MCU*/
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) + HEADER_FOOTER_SIZE;
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Read Version Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 32);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Version CRC ERROR 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) MCU fw CMD ID Read Payload Error - 0x%02x \n", __func__,
+ __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ for (loop = 0 ; loop < VERSION_SIZE ; loop++ )
+ *(fw_version_1335+loop) = mc_ret_data_1335[2+loop];
+
+ ret = ERRCODE_SUCCESS;
+exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+/**
+ * mcu_verify_fw_version:
+ *
+ * Verify the firmware version obtained from the MCU and that found in the
+ * firmware text file present in our driver.
+ *
+ * The return value after verification is as follows:
+ *
+ * - If the version number matches a success value (0) is returned.
+ *
+ * - In case the version number mismatches, a negative value indicating error
+ * is returned.
+ *
+ * - In case the force update bit is set in firmware version in the text
+ * file, a positive value is returned.
+ */
+static int mcu_verify_fw_version(const unsigned char *const fw_version_1335)
+{
+ int loop, i = 0, ret;
+ char txt_fw_version[32] = {0};
+ unsigned long txt_fw_pos = ARRAY_SIZE(g_mcu_fw_buf_1335)-VERSION_FILE_OFFSET;
+
+ /* Get Text Firmware version*/
+ for(loop = txt_fw_pos; loop < (txt_fw_pos+64); loop=loop+2) {
+ *(txt_fw_version+i) = (mcu_bload_ascii2hex(g_mcu_fw_buf_1335[loop]) << 4 |
+ mcu_bload_ascii2hex(g_mcu_fw_buf_1335[loop+1]));
+ i++;
+ }
+
+ /* Check for forced/always update field in the text firmware version*/
+ if(txt_fw_version[17] == '1') {
+
+#ifdef AR1335_DEBUG
+ pr_info("Forced Update Enabled - Firmware Version - (%.32s) \n",
+ fw_version_1335);
+#endif
+
+ ret = 2;
+ }
+ else {
+ for(i = 0; i < VERSION_SIZE; i++) {
+ if(txt_fw_version[i] != fw_version_1335[i]) {
+
+ pr_info("Previous Firmware Version - (%.32s)\n", fw_version_1335);
+
+ ret = -1;
+ break;
+ }
+ }
+
+ if (i == VERSION_SIZE)
+ ret = ERRCODE_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int mcu_bload_get_version(struct i2c_client *client)
+{
+ int ret = 0;
+
+ /*----------------------------- GET VERSION -------------------- */
+
+ /* Write Get Version CMD */
+ g_bload_buf_1335[0] = BL_GET_VERSION;
+ g_bload_buf_1335[1] = ~(BL_GET_VERSION);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != 'y') {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed\n");
+ return -1;
+ }
+
+ /* ---------------- GET VERSION END ------------------- */
+
+ return 0;
+}
+
+static int mcu_bload_erase_flash(struct i2c_client *client)
+{
+ unsigned short int pagenum = 0x0000;
+ int ret = 0, i = 0, checksum = 0;
+
+ /* --------------- ERASE FLASH --------------------- */
+
+ for (i = 0; i < NUM_ERASE_CYCLES; i++) {
+
+ checksum = 0x00;
+ /* Write Erase Pages CMD */
+ g_bload_buf_1335[0] = BL_ERASE_MEM_NS;
+ g_bload_buf_1335[1] = ~(BL_ERASE_MEM_NS);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf_1335[0] = (MAX_PAGES - 1) >> 8;
+ g_bload_buf_1335[1] = (MAX_PAGES - 1) & 0xFF;
+ g_bload_buf_1335[2] = g_bload_buf_1335[0] ^ g_bload_buf_1335[1];
+
+ ret = ar1335_write(client, g_bload_buf_1335, 3);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ for (pagenum = 0; pagenum < MAX_PAGES; pagenum++) {
+ g_bload_buf_1335[(2 * pagenum)] =
+ (pagenum + (i * MAX_PAGES)) >> 8;
+ g_bload_buf_1335[(2 * pagenum) + 1] =
+ (pagenum + (i * MAX_PAGES)) & 0xFF;
+ checksum =
+ checksum ^ g_bload_buf_1335[(2 * pagenum)] ^
+ g_bload_buf_1335[(2 * pagenum) + 1];
+ }
+ g_bload_buf_1335[2 * MAX_PAGES] = checksum;
+
+ ret = ar1335_write(client, g_bload_buf_1335, (2 * MAX_PAGES) + 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ poll_busy:
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] == RESP_BUSY)
+ goto poll_busy;
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info(" ERASE Sector %d success !! \n", i + 1);
+#endif
+ }
+
+ /* ------------ ERASE FLASH END ----------------------- */
+
+ return 0;
+}
+
+static unsigned char mcu_bload_inv_checksum(unsigned char *buf, int len)
+{
+ unsigned int checksum = 0x00;
+ int i = 0;
+
+ if (!buf || !(buf + len))
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ checksum = (checksum + buf[i]);
+ }
+
+ checksum &= (0xFF);
+ return (~(checksum) + 1);
+}
+
+static int mcu_bload_parse_send_cmd(struct i2c_client *client,
+ unsigned char *bytearray, int rec_len)
+{
+ IHEX_RECORD *ihex_rec = NULL;
+ unsigned char checksum = 0, calc_checksum = 0;
+ int i = 0, ret = 0;
+
+ if (!bytearray)
+ return -1;
+
+ ihex_rec = (IHEX_RECORD *) bytearray;
+ ihex_rec->addr = htons(ihex_rec->addr);
+
+ checksum = bytearray[rec_len - 1];
+
+ calc_checksum = mcu_bload_inv_checksum(bytearray, rec_len - 1);
+ if (checksum != calc_checksum) {
+ dev_err(&client->dev," Invalid Checksum 0x%02x != 0x%02x !! \n",
+ checksum, calc_checksum);
+ return -1;
+ }
+
+ if ((ihex_rec->rectype == REC_TYPE_ELA)
+ && (ihex_rec->addr == 0x0000)
+ && (ihex_rec->datasize = 0x02)) {
+ /* Upper 32-bit configuration */
+ g_bload_flashaddr_1335 = (ihex_rec->recdata[0] <<
+ 24) | (ihex_rec->recdata[1]
+ << 16);
+#ifdef AR1335_DEBUG
+ pr_info("Updated Flash Addr = 0x%08x \n",
+ g_bload_flashaddr_1335);
+#endif
+
+ } else if (ihex_rec->rectype == REC_TYPE_DATA) {
+ /* Flash Data into Flashaddr */
+
+ g_bload_flashaddr_1335 =
+ (g_bload_flashaddr_1335 & 0xFFFF0000) | (ihex_rec->addr);
+ g_bload_crc16_1335 ^=
+ mcu_bload_calc_crc16(ihex_rec->recdata, ihex_rec->datasize);
+
+ /* Write Erase Pages CMD */
+ g_bload_buf_1335[0] = BL_WRITE_MEM_NS;
+ g_bload_buf_1335[1] = ~(BL_WRITE_MEM_NS);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf_1335[0] = (g_bload_flashaddr_1335 & 0xFF000000) >> 24;
+ g_bload_buf_1335[1] = (g_bload_flashaddr_1335 & 0x00FF0000) >> 16;
+ g_bload_buf_1335[2] = (g_bload_flashaddr_1335 & 0x0000FF00) >> 8;
+ g_bload_buf_1335[3] = (g_bload_flashaddr_1335 & 0x000000FF);
+ g_bload_buf_1335[4] =
+ g_bload_buf_1335[0] ^ g_bload_buf_1335[1] ^ g_bload_buf_1335[2] ^
+ g_bload_buf_1335[3];
+
+ ret = ar1335_write(client, g_bload_buf_1335, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf_1335[0] = ihex_rec->datasize - 1;
+ checksum = g_bload_buf_1335[0];
+ for (i = 0; i < ihex_rec->datasize; i++) {
+ g_bload_buf_1335[i + 1] = ihex_rec->recdata[i];
+ checksum ^= g_bload_buf_1335[i + 1];
+ }
+
+ g_bload_buf_1335[i + 1] = checksum;
+
+ ret = ar1335_write(client, g_bload_buf_1335, i + 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ poll_busy:
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] == RESP_BUSY)
+ goto poll_busy;
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ } else if (ihex_rec->rectype == REC_TYPE_SLA) {
+ /* Update Instruction pointer to this address */
+
+ } else if (ihex_rec->rectype == REC_TYPE_EOF) {
+ /* End of File - Issue I2C Go Command */
+ return 0;
+ } else {
+
+ /* Unhandled Type */
+ dev_err(&client->dev,"Unhandled Command Type \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_bload_update_fw(struct i2c_client *client)
+{
+ /* exclude NULL character at end of string */
+ unsigned long hex_file_size = ARRAY_SIZE(g_mcu_fw_buf_1335) - 1;
+ unsigned char wbuf[MAX_BUF_LEN];
+ int i = 0, recindex = 0, ret = 0;
+
+ for (i = 0; i < hex_file_size; i++) {
+ if ((recindex == 0) && (g_mcu_fw_buf_1335[i] == ':')) {
+ /* pr_info("Start of a Record \n"); */
+ } else if (g_mcu_fw_buf_1335[i] == CR) {
+ /* No Implementation */
+ } else if (g_mcu_fw_buf_1335[i] == LF) {
+ if (recindex == 0) {
+ /* Parsing Complete */
+ break;
+ }
+
+ /* Analyze Packet and Send Commands */
+ ret = mcu_bload_parse_send_cmd(client, wbuf, recindex);
+ if (ret < 0) {
+ dev_err(&client->dev,"Error in Processing Commands \n");
+ break;
+ }
+
+ recindex = 0;
+
+ } else {
+ /* Parse Rec Data */
+ if ((ret = mcu_bload_ascii2hex(g_mcu_fw_buf_1335[i])) < 0) {
+ dev_err(&client->dev,
+ "Invalid Character - 0x%02x !! \n",
+ g_mcu_fw_buf_1335[i]);
+ break;
+ }
+
+ wbuf[recindex] = (0xF0 & (ret << 4));
+ i++;
+
+ if ((ret = mcu_bload_ascii2hex(g_mcu_fw_buf_1335[i])) < 0) {
+ dev_err(&client->dev,
+ "Invalid Character - 0x%02x !!!! \n",
+ g_mcu_fw_buf_1335[i]);
+ break;
+ }
+
+ wbuf[recindex] |= (0x0F & ret);
+ recindex++;
+ }
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info("Program FLASH Success !! - CRC = 0x%04x \n",
+ g_bload_crc16_1335);
+#endif
+
+ /* ------------ PROGRAM FLASH END ----------------------- */
+
+ return ret;
+}
+
+static int mcu_bload_read(struct i2c_client *client,
+ unsigned int g_bload_flashaddr_1335, char *bytearray,
+ unsigned int len)
+{
+ int ret = 0;
+
+ g_bload_buf_1335[0] = BL_READ_MEM;
+ g_bload_buf_1335[1] = ~(BL_READ_MEM);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf_1335[0] = (g_bload_flashaddr_1335 & 0xFF000000) >> 24;
+ g_bload_buf_1335[1] = (g_bload_flashaddr_1335 & 0x00FF0000) >> 16;
+ g_bload_buf_1335[2] = (g_bload_flashaddr_1335 & 0x0000FF00) >> 8;
+ g_bload_buf_1335[3] = (g_bload_flashaddr_1335 & 0x000000FF);
+ g_bload_buf_1335[4] =
+ g_bload_buf_1335[0] ^ g_bload_buf_1335[1] ^ g_bload_buf_1335[2] ^ g_bload_buf_1335[3];
+
+ ret = ar1335_write(client, g_bload_buf_1335, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ g_bload_buf_1335[0] = len - 1;
+ g_bload_buf_1335[1] = ~(len - 1);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ /* Wait for ACK or NACK */
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ ret = ar1335_read(client, bytearray, len);
+ if (ret < 0) {
+ dev_err(&client->dev,"Read Failed \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_bload_verify_flash(struct i2c_client *client,
+ unsigned short int orig_crc)
+{
+ char bytearray[FLASH_READ_LEN];
+ unsigned short int calc_crc = 0;
+ unsigned int flash_addr = FLASH_START_ADDRESS, i = 0;
+
+ while ((i + FLASH_READ_LEN) <= FLASH_SIZE) {
+ memset(bytearray, 0x0, FLASH_READ_LEN);
+
+ if (mcu_bload_read(
+ client, flash_addr + i, bytearray, FLASH_READ_LEN) < 0) {
+ dev_err(&client->dev," i2c_bload_read FAIL !! \n");
+ return -1;
+ }
+
+ calc_crc ^= mcu_bload_calc_crc16(bytearray, FLASH_READ_LEN);
+ i += FLASH_READ_LEN;
+ }
+
+ if ((FLASH_SIZE - i) > 0) {
+ memset(bytearray, 0x0, FLASH_READ_LEN);
+
+ if (mcu_bload_read(
+ client, flash_addr + i, bytearray, (FLASH_SIZE - i)
+ ) < 0) {
+ dev_err(&client->dev," i2c_bload_read FAIL !! \n");
+ return -1;
+ }
+
+ calc_crc ^= mcu_bload_calc_crc16(bytearray, FLASH_READ_LEN);
+ }
+
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," CRC verification fail !! 0x%04x != 0x%04x \n",
+ orig_crc, calc_crc);
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info(" CRC Verification Success 0x%04x == 0x%04x \n",
+ orig_crc, calc_crc);
+#endif
+
+ return 0;
+}
+
+static int mcu_bload_go(struct i2c_client *client)
+{
+ int ret = 0;
+
+ g_bload_buf_1335[0] = BL_GO;
+ g_bload_buf_1335[1] = ~(BL_GO);
+
+ ret = ar1335_write(client, g_bload_buf_1335, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Failed Read 1 \n");
+ return -1;
+ }
+
+ /* Start Address */
+ g_bload_buf_1335[0] = (FLASH_START_ADDRESS & 0xFF000000) >> 24;
+ g_bload_buf_1335[1] = (FLASH_START_ADDRESS & 0x00FF0000) >> 16;
+ g_bload_buf_1335[2] = (FLASH_START_ADDRESS & 0x0000FF00) >> 8;
+ g_bload_buf_1335[3] = (FLASH_START_ADDRESS & 0x000000FF);
+ g_bload_buf_1335[4] =
+ g_bload_buf_1335[0] ^ g_bload_buf_1335[1] ^ g_bload_buf_1335[2] ^ g_bload_buf_1335[3];
+
+ ret = ar1335_write(client, g_bload_buf_1335, 5);
+ if (ret < 0) {
+ dev_err(&client->dev,"Write Failed \n");
+ return -1;
+ }
+
+ ret = ar1335_read(client, g_bload_buf_1335, 1);
+ if (ret < 0) {
+ dev_err(&client->dev,"Failed Read 1 \n");
+ return -1;
+ }
+
+ if (g_bload_buf_1335[0] != RESP_ACK) {
+ /* NACK Received */
+ dev_err(&client->dev," NACK Received... exiting.. \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mcu_fw_update(struct i2c_client *client, unsigned char *mcu_fw_version)
+{
+ int ret = 0;
+ g_bload_crc16_1335 = 0;
+
+ /*
+ * TODO: Is this necessary? It seems redundant as it's already called before
+ * calling this function.
+ */
+ /* Read Firmware version from bootloader MCU */
+ ret = mcu_bload_get_version(client);
+ if (ret < 0) {
+ dev_err(&client->dev," Error in Get Version \n");
+ goto exit;
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info(" Get Version SUCCESS !! \n");
+#endif
+
+ /* Erase firmware present in the MCU and flash new firmware*/
+ ret = mcu_bload_erase_flash(client);
+ if (ret < 0) {
+ dev_err(&client->dev," Error in Erase Flash \n");
+ goto exit;
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info("Erase Flash Success !! \n");
+#endif
+
+ /* Read the firmware present in the text file */
+ if ((ret = mcu_bload_update_fw(client)) < 0) {
+ dev_err(&client->dev," Write Flash FAIL !! \n");
+ goto exit;
+ }
+
+ /* Verify the checksum for the update firmware */
+ if ((ret = mcu_bload_verify_flash(client, g_bload_crc16_1335)) < 0) {
+ dev_err(&client->dev," verify_flash FAIL !! \n");
+ goto exit;
+ }
+
+ /* Reverting from bootloader mode */
+ /* I2C GO Command */
+ if ((ret = mcu_bload_go(client)) < 0) {
+ dev_err(&client->dev," i2c_bload_go FAIL !! \n");
+ goto exit;
+ }
+
+ if(mcu_fw_version) {
+
+#ifdef AR1335_DEBUG
+ pr_info("(%s) - Firmware Updated - (%.32s)\n",
+ __func__, mcu_fw_version);
+#endif
+
+ }
+ exit:
+ return ret;
+}
+
+static int mcu_count_or_list_ctrls(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_cam_ctrl, int *numctrls)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ uint16_t index = 0;
+ int ret = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ /* Array of Ctrl Info */
+ while (1) {
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL_INFO;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL_INFO;
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+ err = ar1335_write(client, mc_data_1335, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) == 0) {
+ *numctrls = index;
+ break;
+ }
+
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) +
+ HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data_1335[2],
+ payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if(mcu_cam_ctrl != NULL) {
+ int sorted_elem = index - 1, elem = index;
+
+ /* append ctrl info in array */
+ mcu_cam_ctrl[index].ctrl_id =
+ mc_ret_data_1335[2] << 24 | mc_ret_data_1335[3] << 16 | mc_ret_data_1335[4]
+ << 8 | mc_ret_data_1335[5];
+ mcu_cam_ctrl[index].ctrl_type = mc_ret_data_1335[6];
+
+ switch (mcu_cam_ctrl[index].ctrl_type) {
+ case CTRL_STANDARD:
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_min =
+ mc_ret_data_1335[7] << 24 | mc_ret_data_1335[8] << 16
+ | mc_ret_data_1335[9] << 8 | mc_ret_data_1335[10];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_max =
+ mc_ret_data_1335[11] << 24 | mc_ret_data_1335[12] <<
+ 16 | mc_ret_data_1335[13]
+ << 8 | mc_ret_data_1335[14];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_def =
+ mc_ret_data_1335[15] << 24 | mc_ret_data_1335[16] <<
+ 16 | mc_ret_data_1335[17]
+ << 8 | mc_ret_data_1335[18];
+
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_step =
+ mc_ret_data_1335[19] << 24 | mc_ret_data_1335[20] <<
+ 16 | mc_ret_data_1335[21]
+ << 8 | mc_ret_data_1335[22];
+
+ mcu_cam_ctrl[index].mcu_ctrl_index = index;
+ break;
+
+ case CTRL_EXTENDED:
+ /* Not Implemented */
+ break;
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info("Control: ID: 0x%x; Type: %u; min: %d; Max: %d; Def: %d; Step: %u\n",
+ mcu_cam_ctrl[index].ctrl_id,
+ mcu_cam_ctrl[index].ctrl_type,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_min,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_max,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_def,
+ mcu_cam_ctrl[index].ctrl_data.std.ctrl_step
+ );
+#endif
+
+ ctrldb[index] = mcu_cam_ctrl[index].ctrl_id;
+
+ /*
+ * Keep the control list and control db sorted.
+ */
+ while(
+ sorted_elem >= 0 &&
+ (
+ mcu_cam_ctrl[sorted_elem].ctrl_id >
+ mcu_cam_ctrl[elem].ctrl_id
+ )
+ )
+ {
+ ISP_CTRL_INFO swap_ctrl_elem;
+ uint32_t swap_ctrldb_elem;
+
+ /*
+ * Swap the elements in the mcu_cam_ctrl list
+ */
+ memcpy(&swap_ctrl_elem, (mcu_cam_ctrl + sorted_elem), sizeof(ISP_CTRL_INFO));
+ memcpy((mcu_cam_ctrl + sorted_elem), (mcu_cam_ctrl + elem), sizeof(ISP_CTRL_INFO));
+ memcpy((mcu_cam_ctrl + elem), &swap_ctrl_elem, sizeof(ISP_CTRL_INFO));
+
+ /*
+ * Swap the elements in ctrldb
+ */
+ swap_ctrldb_elem = ctrldb[sorted_elem];
+ ctrldb[sorted_elem] = ctrldb[elem];
+ ctrldb[elem] = swap_ctrldb_elem;
+
+ elem = sorted_elem;
+ sorted_elem = elem - 1;
+ }
+ }
+ index++;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+static int mcu_count_or_list_fmts(struct i2c_client *client, ISP_STREAM_INFO *stream_info, int *frm_fmt_size)
+{
+ uint32_t payload_len = 0, err = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0, skip = 0;
+ uint16_t index = 0, mode = 0;
+
+ int loop = 0, num_frates = 0, ret = 0;
+
+ /* Stream Info Variables */
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ /* List all formats from MCU and append to mcu_ar1335_frmfmt array */
+
+ for (index = 0;; index++) {
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_STREAM_INFO;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_STREAM_INFO;
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+ err = ar1335_write(client, mc_data_1335, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) == 0) {
+ if(stream_info == NULL) {
+ *frm_fmt_size = index;
+ } else {
+ *frm_fmt_size = mode;
+ }
+ break;
+ }
+
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) +
+ HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data_1335[2],
+ payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev,
+ " %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev,
+ " %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+ if(stream_info != NULL) {
+ stream_info->fmt_fourcc =
+ mc_ret_data_1335[2] << 24 | mc_ret_data_1335[3] << 16 | mc_ret_data_1335[4]
+ << 8 | mc_ret_data_1335[5];
+ stream_info->width = mc_ret_data_1335[6] << 8 | mc_ret_data_1335[7];
+ stream_info->height = mc_ret_data_1335[8] << 8 | mc_ret_data_1335[9];
+ stream_info->frame_rate_type = mc_ret_data_1335[10];
+
+ switch (stream_info->frame_rate_type) {
+ case FRAME_RATE_DISCRETE:
+ stream_info->frame_rate.disc.frame_rate_num =
+ mc_ret_data_1335[11] << 8 | mc_ret_data_1335[12];
+
+ stream_info->frame_rate.disc.frame_rate_denom =
+ mc_ret_data_1335[13] << 8 | mc_ret_data_1335[14];
+
+ break;
+
+ case FRAME_RATE_CONTINOUS:
+ dev_err(&client->dev,
+ " The Stream format at index 0x%04x has FRAME_RATE_CONTINOUS,"
+ "which is unsupported !! \n", index);
+
+ continue;
+ }
+
+ switch (stream_info->fmt_fourcc) {
+ /*
+ * We check for UYVY here instead of YUYV as the output from the sensor
+ * is UYVY. We swap it to YUYV only making changes in the platform driver.
+ */
+ case V4L2_PIX_FMT_UYVY:
+ /* ar1335_codes is already populated with V4L2_PIX_FMT_YUYV */
+ /* check if width and height are already in array - update frame rate only */
+ for (loop = 0; loop < (mode); loop++) {
+ if ((ar1335_data.mcu_cam_frmfmt[loop].size.width ==
+ stream_info->width)
+ && (ar1335_data.mcu_cam_frmfmt[loop].size.height ==
+ stream_info->height)) {
+
+ num_frates =
+ ar1335_data.mcu_cam_frmfmt[loop].num_framerates;
+ *((int *)(ar1335_data.mcu_cam_frmfmt[loop].framerates) + num_frates)
+ = (int)(stream_info->frame_rate.
+ disc.frame_rate_num /
+ stream_info->frame_rate.
+ disc.frame_rate_denom);
+
+ ar1335_data.mcu_cam_frmfmt[loop].num_framerates++;
+
+ streamdb[index] = loop;
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip) {
+ skip = 0;
+ continue;
+ }
+
+ /* Add Width, Height, Frame Rate array, Mode into mcu_ar1335_frmfmt array */
+ ar1335_data.mcu_cam_frmfmt[mode].size.width = stream_info->width;
+ ar1335_data.mcu_cam_frmfmt[mode].size.height = stream_info->height;
+
+ num_frates = ar1335_data.mcu_cam_frmfmt[mode].num_framerates;
+
+ *(ar1335_data.mcu_cam_frmfmt[mode].framerates + num_frates) =
+ (int)(stream_info->frame_rate.disc.frame_rate_num /
+ stream_info->frame_rate.disc.frame_rate_denom);
+
+ ar1335_data.mcu_cam_frmfmt[mode].num_framerates++;
+
+ ar1335_data.mcu_cam_frmfmt[mode].mode = mode;
+ ar1335_data.mcu_cam_frmfmt[mode].mode = mode;
+ streamdb[index] = mode;
+ mode++;
+ break;
+
+ default:
+ dev_err(&client->dev,
+ " The Stream format at index 0x%04x has format 0x%08x ,"
+ "which is unsupported !! \n", index,
+ stream_info->fmt_fourcc);
+ }
+ }
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+/*
+ * Function to initialise the data related to MCU. Needs to be called
+ * before trying to use them.
+ */
+static int mcu_data_init(struct device *dev, int frm_fmt_size)
+{
+ int loop = 0;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ mcu_ctrl_info = devm_kzalloc(dev, sizeof(ISP_CTRL_INFO) * num_ctrls, GFP_KERNEL);
+ if(!mcu_ctrl_info) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ ctrldb = devm_kzalloc(dev, sizeof(uint32_t) * num_ctrls, GFP_KERNEL);
+ if(!ctrldb) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ stream_info = devm_kzalloc(dev, sizeof(ISP_STREAM_INFO) * (frm_fmt_size + 1), GFP_KERNEL);
+
+ streamdb = devm_kzalloc(dev, sizeof(int) * (frm_fmt_size + 1), GFP_KERNEL);
+ if(!streamdb) {
+ dev_err(dev,"Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ ar1335_data.mcu_cam_frmfmt = devm_kzalloc(dev, sizeof(struct mcu_frmfmt) * (frm_fmt_size), GFP_KERNEL);
+ if(!ar1335_data.mcu_cam_frmfmt) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+
+ for(; loop < frm_fmt_size; loop++) {
+ ar1335_data.mcu_cam_frmfmt[loop].framerates = devm_kzalloc(dev, sizeof(int) * MAX_NUM_FRATES, GFP_KERNEL);
+ if(!ar1335_data.mcu_cam_frmfmt[loop].framerates) {
+ dev_err(dev, "Unable to allocate memory \n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static int mcu_get_sensor_id(struct i2c_client *client, uint16_t * sensor_id)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+
+ int ret = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ /* Read the version info. from Micro controller */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_SENSOR_ID;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_SENSOR_ID;
+ err = ar1335_write(client, mc_data_1335, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) + HEADER_FOOTER_SIZE;
+
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ *sensor_id = mc_ret_data_1335[2] << 8 | mc_ret_data_1335[3];
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+static int mcu_get_cmd_status(struct i2c_client *client,
+ uint8_t * cmd_id, uint16_t * cmd_status,
+ uint8_t * ret_code)
+{
+ uint32_t payload_len = 0;
+ uint8_t orig_crc = 0, calc_crc = 0;
+ int err = 0;
+
+ /* No Semaphore in Get command Status */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 1;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_STATUS;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_STATUS;
+ mc_data_1335[2] = *cmd_id;
+ err = ar1335_write(client, mc_data_1335, 3);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ payload_len = CMD_STATUS_MSG_LEN;
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 3);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ return -EINVAL;
+ }
+
+ *cmd_id = mc_ret_data_1335[2];
+ *cmd_status = mc_ret_data_1335[3] << 8 | mc_ret_data_1335[4];
+ *ret_code = mc_ret_data_1335[payload_len - 1];
+
+ return 0;
+}
+
+static int mcu_isp_init(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /* check current status - if initialized, no need for Init */
+ cmd_id = CMD_ID_INIT_CAM;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n", __func__, __LINE__);
+ return -EIO;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+
+#ifdef AR1335_DEBUG
+ pr_info(" Already Initialized !! \n");
+#endif
+
+ return 0;
+ }
+
+ /* call ISP init command */
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_INIT_CAM;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_INIT_CAM;
+ err = ar1335_write(client, mc_data_1335, 2);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ return -EIO;
+ }
+
+ while (--retry > 0) {
+ /* Some Sleep for init to process */
+ mdelay(5);
+
+ cmd_id = CMD_ID_INIT_CAM;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n",
+ __func__, __LINE__);
+ return -EIO;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ ((retcode == ERRCODE_SUCCESS) || (retcode == ERRCODE_ALREADY))) {
+
+#ifdef AR1335_DEBUG
+ pr_info(" ISP Already Initialized !! \n");
+#endif
+
+ return 0;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Init Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ return -EIO;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int mcu_get_ctrl_ui(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ui_info, int index)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ int ret = 0, i = 0, err = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL_UI_INFO;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL_UI_INFO;
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+ err = ar1335_write(client, mc_data_1335, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) + HEADER_FOOTER_SIZE;
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data_1335[2], payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ strncpy((char *)mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_name, &mc_ret_data_1335[2],MAX_CTRL_UI_STRING_LEN);
+
+ mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_type = mc_ret_data_1335[34];
+ mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags = mc_ret_data_1335[35] << 8 |
+ mc_ret_data_1335[36];
+
+ if (mcu_ui_info->ctrl_ui_data.ctrl_ui_info.ctrl_ui_type == V4L2_CTRL_TYPE_MENU) {
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem = mc_ret_data_1335[37];
+
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu =
+ devm_kzalloc(&client->dev,((mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem +1) * sizeof(char *)), GFP_KERNEL);
+ for (i = 0; i < mcu_ui_info->ctrl_ui_data.ctrl_menu_info.num_menu_elem; i++) {
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i] =
+ devm_kzalloc(&client->dev,MAX_CTRL_UI_STRING_LEN, GFP_KERNEL);
+ strncpy((char *)mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i],
+ &mc_ret_data_1335[38 +(i *MAX_CTRL_UI_STRING_LEN)], MAX_CTRL_UI_STRING_LEN);
+
+#ifdef AR1335_DEBUG
+ pr_info(" Menu Element %d : %s \n",
+ i, mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i]);
+#endif
+
+ }
+
+ mcu_ui_info->ctrl_ui_data.ctrl_menu_info.menu[i] = NULL;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+
+}
+
+static int mcu_isp_configuration(uint8_t cmd_id,struct i2c_client *client)
+{
+ unsigned char mc_data_1335[100];
+ uint32_t payload_len = 0;
+
+ uint16_t payload_data;
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+ /* First Txn Payload length = 0 */
+ payload_len = 2;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = cmd_id;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = cmd_id;
+
+ switch(cmd_id) {
+ case CMD_ID_LANE_CONFIG:
+ /*Lane configuration */
+ payload_data = ar1335_data.mipi_lane_config == 4 ? NUM_LANES_4: NUM_LANES_2;
+ mc_data_1335[2] = payload_data >> 8;
+ mc_data_1335[3] = payload_data & 0xFF;
+ break;
+ case CMD_ID_MIPI_CLK_CONFIG:
+ /* MIPI CLK Configuration */
+ payload_data = ar1335_data.mipi_clk_config;
+ mc_data_1335[2] = payload_data >> 8;
+ mc_data_1335[3] = payload_data & 0xFF;
+ break;
+ default:
+ dev_err(&client->dev, "MCU ISP CONF Error\n");
+ err = -1;
+ goto exit;
+ }
+
+ /* CRC*/
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], payload_len);
+ err = ar1335_write(client, mc_data_1335, payload_len+3);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+
+ while (--retry > 0) {
+ msleep(20);
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Error \n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_ISP_UNINIT) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_ISP_UNINIT))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+ return err;
+}
+
+static int mcu_stream_config(struct i2c_client *client, uint32_t format,
+ int mode, int frate_index)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0, index = 0xFFFF;
+ uint8_t retcode = 0, cmd_id = 0;
+ int loop = 0, ret = 0, err = 0, retry = 1000;
+ static uint16_t prev_index = 0xFFFE;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ cmd_id = CMD_ID_STREAM_CONFIG;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n", __func__, __LINE__);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status != MCU_CMD_STATUS_SUCCESS) ||
+ (retcode != ERRCODE_SUCCESS)) {
+ dev_err(&client->dev,
+ " ISP is Unintialized or Busy STATUS = 0x%04x Errcode = 0x%02x !! \n",
+ cmd_status, retcode);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ for (loop = 0;(&streamdb[loop]) != NULL; loop++) {
+ pr_info("streamdb[%d]=%d, mode=%d",loop,streamdb[loop],mode);
+ if (streamdb[loop] == mode) {
+ index = loop + frate_index;
+ break;
+ }
+ }
+
+#ifdef AR1335_DEBUG
+ pr_info(" Index = 0x%04x , format = 0x%08x, width = %hu,"
+ " height = %hu, frate num = %hu \n", index, format,
+ ar1335_data.mcu_cam_frmfmt[mode].size.width,
+ ar1335_data.mcu_cam_frmfmt[mode].size.height,
+ ar1335_data.mcu_cam_frmfmt[mode].framerates[frate_index]);
+#endif
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if(prev_index == index) {
+#ifdef AR1335_DEBUG
+ pr_info("Skipping Previous mode set ... \n");
+#endif
+ ret = 0;
+ goto exit;
+ }
+
+issue_cmd:
+ /* First Txn Payload length = 0 */
+ payload_len = 14;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_STREAM_CONFIG;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_STREAM_CONFIG;
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+
+ /* Format Fourcc - currently only YUYV */
+ mc_data_1335[4] = format >> 24;
+ mc_data_1335[5] = format >> 16;
+ mc_data_1335[6] = format >> 8;
+ mc_data_1335[7] = format & 0xFF;
+
+ /* width */
+ mc_data_1335[8] = ar1335_data.mcu_cam_frmfmt[mode].size.width >> 8;
+ mc_data_1335[9] = ar1335_data.mcu_cam_frmfmt[mode].size.width & 0xFF;
+
+ /* height */
+ mc_data_1335[10] = ar1335_data.mcu_cam_frmfmt[mode].size.height >> 8;
+ mc_data_1335[11] = ar1335_data.mcu_cam_frmfmt[mode].size.height & 0xFF;
+
+ /* frame rate num */
+ mc_data_1335[12] = ar1335_data.mcu_cam_frmfmt[mode].framerates[frate_index] >> 8;
+ mc_data_1335[13] = ar1335_data.mcu_cam_frmfmt[mode].framerates[frate_index] & 0xFF;
+
+ /* frame rate denom */
+ mc_data_1335[14] = 0x00;
+ mc_data_1335[15] = 0x01;
+
+ mc_data_1335[16] = errorcheck(&mc_data_1335[2], 14);
+ err = ar1335_write(client, mc_data_1335, 17);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ cmd_id = CMD_ID_STREAM_CONFIG;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev,
+ " %s(%d) MCU GET CMD Status Error : loop : %d \n",
+ __func__, __LINE__, loop);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+ ret = 0;
+ goto exit;
+ }
+
+ if(retcode == ERRCODE_AGAIN) {
+ /* Issue Command Again if Set */
+ retry = 1000;
+ goto issue_cmd;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Delay after retry */
+ mdelay(10);
+ }
+
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -ETIMEDOUT;
+
+exit:
+ if(!ret)
+ prev_index = index;
+
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+static int mcu_isp_power_down(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_ISP_PDOWN;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_ISP_PDOWN;
+ err = ar1335_write(client, mc_data_1335, 2);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ msleep(20);
+ cmd_id = CMD_ID_ISP_PDOWN;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Get Status Error \n",
+ __func__, __LINE__);
+ err = -EINVAL;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_ISP_PWDN) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status,
+ retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+ return err;
+}
+
+static int mcu_isp_power_wakeup(struct i2c_client *client)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0;
+ uint8_t retcode = 0, cmd_id = 0;
+ int retry = 1000, err = 0;
+
+ /*lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+ /* First Txn Payload length = 0 */
+ payload_len = 0;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_ISP_PUP;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_ISP_PUP;
+ err = ar1335_write(client, mc_data_1335, 2);
+ if (err != 0) {
+ dev_err(&client->dev, " %s(%d) Error - %d \n",
+ __func__, __LINE__, err);
+ goto exit;
+ }
+
+ while (--retry > 0) {
+ msleep(20);
+ cmd_id = CMD_ID_ISP_PUP;
+ if (mcu_get_cmd_status(client, &cmd_id, &cmd_status, &retcode) <
+ 0) {
+ dev_err(&client->dev, " %s(%d) Error \n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ ((retcode == ERRCODE_SUCCESS) || retcode == ERRCODE_ALREADY)) {
+ err = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ err = -EIO;
+ goto exit;
+ }
+
+ }
+
+ err = -ETIMEDOUT;
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+ return err;
+}
+
+static int mcu_set_ctrl(struct i2c_client *client, uint32_t arg_ctrl_id,
+ uint8_t ctrl_type, int32_t curr_val)
+{
+ uint32_t payload_len = 0;
+
+ uint16_t cmd_status = 0, index = 0xFFFF;
+ uint8_t retcode = 0, cmd_id = 0;
+ int loop = 0, ret = 0, err = 0;
+ uint32_t ctrl_id = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ ctrl_id = arg_ctrl_id;
+
+ /* call ISP Ctrl config command */
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == ctrl_id) {
+ index = mcu_ctrl_info[loop].mcu_ctrl_index;
+ break;
+ }
+ }
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* First Txn Payload length = 0 */
+ payload_len = 11;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_SET_CTRL;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ /* Second Txn */
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_SET_CTRL;
+
+ /* Index */
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+
+ /* Control ID */
+ mc_data_1335[4] = ctrl_id >> 24;
+ mc_data_1335[5] = ctrl_id >> 16;
+ mc_data_1335[6] = ctrl_id >> 8;
+ mc_data_1335[7] = ctrl_id & 0xFF;
+
+ /* Ctrl Type */
+ mc_data_1335[8] = ctrl_type;
+
+ /* Ctrl Value */
+ mc_data_1335[9] = curr_val >> 24;
+ mc_data_1335[10] = curr_val >> 16;
+ mc_data_1335[11] = curr_val >> 8;
+ mc_data_1335[12] = curr_val & 0xFF;
+
+ /* CRC */
+ mc_data_1335[13] = errorcheck(&mc_data_1335[2], 11);
+
+ err = ar1335_write(client, mc_data_1335, 14);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ while (1) {
+ cmd_id = CMD_ID_SET_CTRL;
+ if (mcu_get_cmd_status(
+ client, &cmd_id, &cmd_status, &retcode) < 0) {
+ dev_err(&client->dev," %s(%d) Error \n",
+ __func__, __LINE__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if ((cmd_status == MCU_CMD_STATUS_SUCCESS) &&
+ (retcode == ERRCODE_SUCCESS)) {
+ ret = 0;
+ goto exit;
+ }
+
+ if ((retcode != ERRCODE_BUSY) &&
+ ((cmd_status != MCU_CMD_STATUS_PENDING))) {
+ dev_err(&client->dev,
+ "(%s) %d ISP Error STATUS = 0x%04x RET = 0x%02x\n",
+ __func__, __LINE__, cmd_status, retcode);
+ ret = -EIO;
+ goto exit;
+ }
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+static int mcu_get_ctrl(struct i2c_client *client, uint32_t arg_ctrl_id,
+ uint8_t * ctrl_type, int32_t * curr_val)
+{
+ uint32_t payload_len = 0;
+ uint8_t errcode = ERRCODE_SUCCESS, orig_crc = 0, calc_crc = 0;
+ uint16_t index = 0xFFFF;
+ int loop = 0, ret = 0, err = 0;
+
+ uint32_t ctrl_id = 0;
+
+ /* lock semaphore */
+ mutex_lock(&mcu_i2c_mutex_1335);
+
+ ctrl_id = arg_ctrl_id;
+
+ /* Read the Ctrl Value from Micro controller */
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == ctrl_id) {
+ index = mcu_ctrl_info[loop].mcu_ctrl_index;
+ break;
+ }
+ }
+
+ if (index == 0xFFFF) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (
+ mcu_ctrl_info[loop].ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags &
+ V4L2_CTRL_FLAG_WRITE_ONLY
+ ) {
+ ret = -EACCES;
+ goto exit;
+ }
+
+ /* First Txn Payload length = 2 */
+ payload_len = 2;
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL;
+ mc_data_1335[2] = payload_len >> 8;
+ mc_data_1335[3] = payload_len & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+
+ ar1335_write(client, mc_data_1335, TX_LEN_PKT);
+
+ mc_data_1335[0] = CMD_SIGNATURE;
+ mc_data_1335[1] = CMD_ID_GET_CTRL;
+ mc_data_1335[2] = index >> 8;
+ mc_data_1335[3] = index & 0xFF;
+ mc_data_1335[4] = errorcheck(&mc_data_1335[2], 2);
+ err = ar1335_write(client, mc_data_1335, 5);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ err = ar1335_read(client, mc_ret_data_1335, RX_LEN_PKT);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[4];
+ calc_crc = errorcheck(&mc_ret_data_1335[2], 2);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -1;
+ goto exit;
+ }
+
+ if (((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) == 0) {
+ ret = -EIO;
+ goto exit;
+ }
+
+ errcode = mc_ret_data_1335[5];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EIO;
+ goto exit;
+ }
+
+ payload_len =
+ ((mc_ret_data_1335[2] << 8) | mc_ret_data_1335[3]) + HEADER_FOOTER_SIZE;
+ memset(mc_ret_data_1335, 0x00, payload_len);
+ err = ar1335_read(client, mc_ret_data_1335, payload_len);
+ if (err != 0) {
+ dev_err(&client->dev," %s(%d) Error - %d \n", __func__,
+ __LINE__, err);
+ ret = -EIO;
+ goto exit;
+ }
+
+ /* Verify CRC */
+ orig_crc = mc_ret_data_1335[payload_len - 2];
+ calc_crc =
+ errorcheck(&mc_ret_data_1335[2], payload_len - HEADER_FOOTER_SIZE);
+ if (orig_crc != calc_crc) {
+ dev_err(&client->dev," %s(%d) CRC 0x%02x != 0x%02x \n",
+ __func__, __LINE__, orig_crc, calc_crc);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Verify Errcode */
+ errcode = mc_ret_data_1335[payload_len - 1];
+ if (errcode != ERRCODE_SUCCESS) {
+ dev_err(&client->dev," %s(%d) Errcode - 0x%02x \n",
+ __func__, __LINE__, errcode);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* Ctrl type starts from index 6 */
+
+ *ctrl_type = mc_ret_data_1335[6];
+
+ switch (*ctrl_type) {
+ case CTRL_STANDARD:
+ *curr_val =
+ mc_ret_data_1335[7] << 24 | mc_ret_data_1335[8] << 16 | mc_ret_data_1335[9]
+ << 8 | mc_ret_data_1335[10];
+ break;
+
+ case CTRL_EXTENDED:
+ /* Not Implemented */
+ break;
+ }
+
+ exit:
+ /* unlock semaphore */
+ mutex_unlock(&mcu_i2c_mutex_1335);
+
+ return ret;
+}
+
+/*
+ * ---------------------------------------------------------
+ * END of MCU realed functions
+ * ---------------------------------------------------------
+ */
+
+static void toggle_gpio(unsigned int gpio, int val)
+{
+ if (gpio_cansleep(gpio)){
+ gpio_direction_output(gpio,val);
+ gpio_set_value_cansleep(gpio, val);
+ } else{
+ gpio_direction_output(gpio,val);
+ gpio_set_value(gpio, val);
+ }
+}
+
+static int ar1335_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
+{
+ uint32_t index = 0;
+ int loop;
+
+ if (sd == NULL || qm == NULL)
+ return -EINVAL;
+
+ for (loop = 0; loop < num_ctrls; loop++) {
+ if (ctrldb[loop] == qm->id) {
+ index = loop;
+ break;
+ }
+ }
+
+ if (loop == num_ctrls) {
+ return -EINVAL;
+ }
+
+ if (
+ !(
+ 0 <= qm->index &&
+ qm->index < mcu_ctrl_info[index].ctrl_ui_data.ctrl_menu_info.num_menu_elem
+ )
+ ) {
+ return -EINVAL;
+ }
+
+ /*
+ * Copy the name of the menu.
+ *
+ * We deal only with V4L2_CTRL_TYPE_MENU and not
+ * V4L2_CTRL_TYPE_INTEGER_MENU. So, this should be
+ * enough.
+ */
+ strcpy(qm->name, mcu_ctrl_info[index].ctrl_ui_data.ctrl_menu_info.menu[qm->index]);
+
+ /*
+ * Set the reserved to zero as mentioned in spec
+ */
+ qm->reserved = 0;
+
+ return 0;
+}
+
+static int ar1335_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ int index, ctrl_index = -1, ctrl_id;
+ bool next_ctrl = (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL);
+
+ if (sd == NULL || qc == NULL)
+ return -EINVAL;
+
+ if (next_ctrl) {
+ ctrl_id = qc->id & (~V4L2_CTRL_FLAG_NEXT_CTRL);
+
+ /*
+ * Ignore the V4L2_CTRL_FLAG_NEXT_COMPOUND for now
+ */
+ ctrl_id = ctrl_id & (~V4L2_CTRL_FLAG_NEXT_COMPOUND);
+ }
+ else {
+ /*
+ * Assume we've just got the control ID itself
+ * directly.
+ */
+ ctrl_id = qc->id;
+ }
+
+ if (ctrl_id) {
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ctrl_id) {
+ ctrl_index = (next_ctrl) ? index + 1 : index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ /*
+ * We do not know about this control
+ */
+ return -EINVAL;
+ }
+ else if (
+ next_ctrl &&
+ index == num_ctrls - 1
+ )
+ {
+ /*
+ * We've got a request for the control
+ * after the last one.
+ */
+ return -EINVAL;
+ }
+ }
+ else if (next_ctrl) {
+ ctrl_index = 0;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ if (
+ mcu_ctrl_info[ctrl_index].ctrl_type == CTRL_STANDARD
+ ) {
+ /*
+ * We cannot use `v4l2_ctrl_query_fill` instead of manually filling
+ * the details even for standard controls as we sometimes implement our
+ * own version for some controls.
+ *
+ * e.g., V4L2_CID_FOCUS_AUTO has a max value of 1 according to standard
+ * but our version of it has a max value of 5.
+ */
+ qc->id = mcu_ctrl_info[ctrl_index].ctrl_id;
+
+ strcpy(qc->name, mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_name);
+
+ qc->type = mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_ui_type;
+ qc->flags = mcu_ctrl_info[ctrl_index].ctrl_ui_data.ctrl_ui_info.ctrl_ui_flags;
+
+ qc->minimum = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min;
+ qc->maximum = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max;
+ qc->step = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_step;
+ qc->default_value = mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_def;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ar1335_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = ar1335_data.i2c_client;
+ int err = 0;
+ uint8_t ctrl_type = 0;
+ int ctrl_val = 0;
+
+ if (sd == NULL || ctrl == NULL)
+ return -EINVAL;
+
+ if ((err = mcu_get_ctrl(client, ctrl->id, &ctrl_type, &ctrl_val)) < 0) {
+ return err;
+ }
+
+ if (ctrl_type == CTRL_STANDARD) {
+ ctrl->value = ctrl_val;
+ } else {
+ /* Not Implemented */
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int ar1335_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = ar1335_data.i2c_client;
+ int err = 0, index, ctrl_index = 0;
+
+ if (sd == NULL || ctrl == NULL)
+ return -EINVAL;
+
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ctrl->id) {
+ ctrl_index = index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ return -EINVAL;
+ }
+
+ if (
+ ctrl->value < mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min ||
+ ctrl->value > mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max
+ )
+ return -ERANGE;
+
+ if ((err =
+ mcu_set_ctrl(client, ctrl->id, CTRL_STANDARD, ctrl->value)) < 0) {
+ dev_err(&client->dev," %s (%d ) \n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int ar1335_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i, err = 0;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ struct v4l2_control ctrl = {
+ .id = ext_ctrl->id,
+ };
+
+ err = ar1335_g_ctrl(sd, &ctrl);
+ if (err) {
+ ctrls->error_idx = ctrls->count;
+ break;
+ }
+ else {
+ ext_ctrl->value = ctrl.value;
+ }
+ }
+
+ return err;
+}
+
+static int ar1335_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ int ctrl_index = 0, index;
+
+ for (index = 0; index < num_ctrls; index++) {
+ if (ctrldb[index] == ext_ctrl->id) {
+ ctrl_index = index;
+ break;
+ }
+ }
+
+ if (index == num_ctrls) {
+ ctrls->error_idx = ext_ctrl->id;
+ return -EINVAL;
+ }
+
+ if (
+ ext_ctrl->value < mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_min ||
+ ext_ctrl->value > mcu_ctrl_info[ctrl_index].ctrl_data.std.ctrl_max
+ ) {
+ ctrls->error_idx = ext_ctrl->id;
+ return -ERANGE;
+ }
+ }
+
+ return 0;
+
+}
+
+static int ar1335_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ int i, err = 0;
+
+ if (sd == NULL || ctrls == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ext_ctrl = ctrls->controls + i;
+ struct v4l2_control ctrl = {
+ .id = ext_ctrl->id,
+ .value = ext_ctrl->value
+ };
+
+ err = ar1335_s_ctrl(sd, &ctrl);
+ if (err) {
+ /*
+ * TODO: We would have to indicate whether there
+ * is an issue in validation or in the
+ * hardware by correctly setting the error_idx
+ * to count only when the validation failed
+ * and setting it to index when there is an
+ * issue in communication with the hardware.
+ *
+ * For now, just return the count for all cases.
+ */
+ ctrls->error_idx = ctrls->count;
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int ar1335_enum_frameintervals(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_interval_enum *fival)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int j;
+
+ if (fival->width == 0 || fival->height == 0)
+ {
+ dev_err(&client->dev, "Please assign width and height.\n");
+ return -EINVAL;
+ }
+
+ if (fival->code != ar1335_data.fmt.code)
+ {
+ return -EINVAL;
+ }
+
+ for (j = 0; j < ar1335_data.num_frm_fmts; j++) {
+ if (
+ fival->width == ar1335_data.mcu_cam_frmfmt[j].size.width &&
+ fival->height == ar1335_data.mcu_cam_frmfmt[j].size.height
+ ) {
+ if (fival->index >= ar1335_data.mcu_cam_frmfmt[j].num_framerates)
+ {
+ return -EINVAL;
+ }
+
+ fival->interval.numerator = 1;
+ fival->interval.denominator = ar1335_data.mcu_cam_frmfmt[j].framerates[fival->index];
+
+ return 0;
+ }
+ }
+ return -EINVAL;
+
+}
+
+static int ar1335_enum_framesizes(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ar1335_data.num_frm_fmts)
+ {
+ return -EINVAL;
+ }
+
+ if (fse->code != ar1335_data.fmt.code)
+ {
+ return -EINVAL;
+ }
+
+ fse->max_width = ar1335_data.mcu_cam_frmfmt[fse->index].size.width;
+ fse->min_width = fse->max_width;
+
+ fse->max_height = ar1335_data.mcu_cam_frmfmt[fse->index].size.height;
+ fse->min_height = fse->max_height;
+
+ return 0;
+}
+
+static int ar1335_enum_mbus_code(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= AR1335_MAX_FORMAT_SUPPORTED)
+ return -EINVAL;
+
+ code->code = ar1335_data.fmt.code;
+
+ return 0;
+}
+
+static int ar1335_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ if (!enable) {
+ /* Perform Stream Off Sequence - if any */
+ }
+
+ /* Perform Stream On Sequence - if any */
+ mdelay(10);
+
+ return 0;
+}
+
+static int ar1335_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+ int mode = ar1335_data.streamcap.capturemode;
+
+ param->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
+
+ param->parm.capture.timeperframe.denominator =
+ ar1335_data.mcu_cam_frmfmt[mode].framerates[ar1335_data.frate_index];
+ param->parm.capture.timeperframe.numerator = 1;
+
+ return 0;
+}
+
+static int ar1335_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = 0, err = 0;
+ int mode = ar1335_data.streamcap.capturemode;
+ int fourcc = ar1335_data.pix.pixelformat;
+
+ param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ memset(param->parm.capture.reserved, 0, 4*sizeof(u32));
+
+ if (
+ param->parm.capture.timeperframe.denominator == 0 &&
+ param->parm.capture.timeperframe.numerator == 0 &&
+ ar1335_data.mcu_cam_frmfmt[mode].num_framerates == 1
+ ) {
+ param->parm.capture.timeperframe.denominator =
+ ar1335_data.mcu_cam_frmfmt[mode].framerates[ar1335_data.frate_index];
+ param->parm.capture.timeperframe.numerator = 1;
+ /*
+ * We would have to reset the frame interval to a
+ * nominal value in this case but as we just have one
+ * frame interval we just return success.
+ */
+ return 0;
+ }
+
+ if (param->parm.capture.timeperframe.numerator != 1) {
+ dev_err(&client->dev, "Invalid numerator for timeperframe\n");
+ return -EINVAL;
+ }
+
+ for (ret = 0; ret < ar1335_data.mcu_cam_frmfmt[mode].num_framerates;
+ ret++) {
+ if ((ar1335_data.mcu_cam_frmfmt[mode].framerates[ret] ==
+ param->parm.capture.timeperframe.denominator)) {
+ ar1335_data.frate_index = ret;
+
+ /* call stream config with width, height, frame rate */
+ err =
+ mcu_stream_config(client, fourcc, mode,
+ ar1335_data.frate_index);
+ if (err < 0) {
+ dev_err(&client->dev, "%s: Failed stream_config \n", __func__);
+ return err;
+ }
+
+ mdelay(10);
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ar1335_s_power(struct v4l2_subdev *sd, int on)
+{
+
+ /* Perform Power On/Off Sequence - if any */
+ return 0;
+}
+
+static int ar1335_get_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *format)
+{
+ int ret = 0;
+
+ if (format->pad)
+ return -EINVAL;
+
+ format->format.code = ar1335_data.fmt.code;
+ format->format.colorspace = ar1335_data.fmt.colorspace;
+ format->format.field = V4L2_FIELD_NONE;
+
+ format->format.width = ar1335_data.pix.width;
+ format->format.height = ar1335_data.pix.height;
+
+ return ret;
+}
+
+static int ar1335_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ int ret = 0, i;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int flag = 0, err = 0;
+
+ format->format.code = ar1335_data.fmt.code;
+ format->format.colorspace = ar1335_data.fmt.colorspace;
+ format->format.field = V4L2_FIELD_NONE;
+
+ for (i = 0; i < ar1335_data.num_frm_fmts ; i++) {
+ if (
+ ar1335_data.mcu_cam_frmfmt[i].size.width == format->format.width &&
+ ar1335_data.mcu_cam_frmfmt[i].size.height == format->format.height
+ ) {
+ printk("resolution equ width= %d \n",ar1335_data.mcu_cam_frmfmt[i].size.width);
+ printk("resolution equ height= %d \n",ar1335_data.mcu_cam_frmfmt[i].size.height);
+ flag = 1;
+ break;
+ }
+ printk("ar1335_resolution width= %d \n",ar1335_data.mcu_cam_frmfmt[i].size.width);
+ printk("ar1335_resolution height= %d \n",ar1335_data.mcu_cam_frmfmt[i].size.height);
+ printk("format_resolution width= %d \n",format->format.width);
+ printk("format_resolution height= %d \n",format->format.height);
+ }
+
+ if(flag == 0) {
+ format->format.width = ar1335_data.pix.width;
+ format->format.height = ar1335_data.pix.height;
+ }
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ {
+ return 0;
+ }
+
+ /* call stream config with width, height, frame rate */
+ err =
+ mcu_stream_config(client, ar1335_data.pix.pixelformat, ar1335_data.mcu_cam_frmfmt[i].mode,
+ ar1335_data.frate_index);
+ if (err < 0) {
+ dev_err(&client->dev, "%s: Failed stream_config \n", __func__);
+ return err;
+ }
+
+ ar1335_data.pix.width = format->format.width;
+ ar1335_data.pix.height = format->format.height;
+ ar1335_data.streamcap.capturemode = ar1335_data.mcu_cam_frmfmt[i].mode;
+
+ mdelay(10);
+
+ return ret;
+}
+
+static int ar1335_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ar1335_subdev_video_ops = {
+ .g_parm = ar1335_g_parm,
+ .s_parm = ar1335_s_parm,
+ .s_stream = ar1335_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ar1335_subdev_pad_ops = {
+ .enum_frame_size = ar1335_enum_framesizes,
+ .enum_frame_interval = ar1335_enum_frameintervals,
+ .enum_mbus_code = ar1335_enum_mbus_code,
+ .set_fmt = ar1335_set_fmt,
+ .get_fmt = ar1335_get_fmt,
+};
+
+static struct v4l2_subdev_core_ops ar1335_subdev_core_ops = {
+ .s_power = ar1335_s_power,
+ .queryctrl = ar1335_queryctrl,
+ .g_ctrl = ar1335_g_ctrl,
+ .s_ctrl = ar1335_s_ctrl,
+ .g_ext_ctrls = ar1335_g_ext_ctrls,
+ .s_ext_ctrls = ar1335_s_ext_ctrls,
+ .try_ext_ctrls = ar1335_try_ext_ctrls,
+ .querymenu = ar1335_querymenu,
+};
+
+static struct v4l2_subdev_ops ar1335_subdev_ops = {
+ .core = &ar1335_subdev_core_ops,
+ .video = &ar1335_subdev_video_ops,
+ .pad = &ar1335_subdev_pad_ops,
+};
+
+static const struct media_entity_operations ar1335_sd_media_ops = {
+ .link_setup = ar1335_link_setup,
+};
+
+static int ar1335_init(struct i2c_client *client)
+{
+ u32 tgt_xclk; /* target xclk */
+ int ret = 0;
+
+ ar1335_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ar1335_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)AR1335_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)AR1335_XCLK_MIN);
+ ar1335_data.mclk = tgt_xclk;
+
+#ifdef AR1335_DEBUG
+ pr_info("mclk: %d MHz\n", tgt_xclk / 1000000);
+#endif
+
+ ret = mcu_stream_config(client, ar1335_data.pix.pixelformat,
+ ar1335_data.streamcap.capturemode,
+ ar1335_data.frate_index);
+
+ return ret;
+}
+
+static int ar1335_ctrls_init(ISP_CTRL_INFO *mcu_cam_ctrls)
+{
+ struct i2c_client *client = NULL;
+ int numctrls = 0;
+ int err = 0, i = 0;
+
+ client = ar1335_data.i2c_client;
+
+ if (mcu_cam_ctrls == NULL)
+ {
+ dev_err(
+ &client->dev,
+ "%s: MCU control data hasn't been allocated\n",
+ __func__
+ );
+ return -EINVAL;
+ }
+ /*
+ * Enumerate the controls from the MCU
+ */
+ err = mcu_count_or_list_ctrls(client, mcu_cam_ctrls, &numctrls);
+ if (err < 0) {
+ dev_err(&client->dev, "Unable to enumerate the controls in the sensor\n");
+ return err;
+ }
+
+ for (i = 0; i < numctrls; i++) {
+ if (mcu_cam_ctrls[i].ctrl_type == CTRL_STANDARD) {
+ err = mcu_get_ctrl_ui(client, &mcu_ctrl_info[i], mcu_ctrl_info[i].mcu_ctrl_index);
+ if (err != ERRCODE_SUCCESS) {
+ dev_err(&client->dev, "Error Enumerating Control 0x%08x !! \n",
+ mcu_ctrl_info[i].ctrl_id);
+ return err;
+ }
+ else if (
+ mcu_ctrl_info[i].ctrl_ui_data.ctrl_ui_info.ctrl_ui_type ==
+ V4L2_CTRL_TYPE_MENU
+ ) {
+ mcu_ctrl_info[i].ctrl_data.std.ctrl_step = 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int ar1335_verify_mcu(struct i2c_client *client)
+{
+ int ret = 0, try = 0;
+ unsigned char fw_version_1335[32] = {0};
+
+ if (client == NULL)
+ {
+ dev_err(&client->dev, "%s: Invalid I2C client parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Try to boot the MCU into firmware mode.
+ *
+ * We do this only when the reset_gpio and pwdn_gpio are
+ * available.
+ */
+ if (gpios_available_1335())
+ {
+ toggle_gpio(pwdn_gpio, 0);
+ msleep(10);
+ toggle_gpio(reset_gpio, 0);
+ msleep(10);
+ toggle_gpio(reset_gpio, 1);
+ msleep(500);
+
+ for(try = 0; try < 10; try++) {
+ ret = mcu_get_fw_version(client, fw_version_1335);
+ if(ret < 0) {
+ msleep(100);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version_1335);
+ }
+ else
+ {
+ dev_dbg(
+ &client->dev,
+ "Could not read the firmware version from the MCU\n"
+ );
+ pr_info(" Could not read the firmware version from the MCU, tries=%d\n", try+1);
+ }
+
+ /*
+ * Try booting and flashing in bootloader mode when an error is detected
+ * or the force update bit is set in the firmware version
+ */
+ if (ret != 0) {
+ int loop = 0;
+
+ /*
+ * Verification of the MCU in firmware mode failed so
+ * try to boot the MCU in bootloader mode.
+ */
+
+ pr_info(" Trying to Detect Bootloader mode\n");
+
+ if (gpios_available_1335())
+ {
+ toggle_gpio(reset_gpio, 0);
+ msleep(10);
+ toggle_gpio(pwdn_gpio, 1);
+ msleep(100);
+ toggle_gpio(reset_gpio, 1);
+ msleep(100);
+ }
+
+ for(loop = 0; loop < 10; loop++) {
+ ret = mcu_bload_get_version(client);
+ if (ret < 0) {
+ /* Trial and Error for 1 second (100ms * 10) */
+ msleep(100);
+ continue;
+ } else {
+#ifdef AR1335_DEBUG
+ pr_info(" Get Bload Version Success\n");
+#endif
+ break;
+ }
+ }
+
+ if(loop == 10) {
+ dev_err(&client->dev, "Error getting firmware version in bootloader mode\n");
+ return -EINVAL;
+ }
+
+ if (mcu_fw_update(client, NULL) < 0) {
+ dev_err(&client->dev, "Error when trying to update the firmware\n");
+ return -EFAULT;
+ }
+
+ if (gpios_available_1335())
+ {
+ toggle_gpio(pwdn_gpio, 0);
+ }
+
+ /* Allow FW Updated MCU to reboot */
+ msleep(500);
+
+ /*
+ * Ensure the firmware has been flashed correctly by getting the version
+ * of the firmware (in firmware mode).
+ */
+ for(loop = 0; loop < 100; loop++) {
+ ret = mcu_get_fw_version(client, fw_version_1335);
+
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version_1335);
+ }
+
+ if (ret < 0) {
+ /* Trial and Error for 10 seconds (100ms * 100) */
+ msleep(100);
+ continue;
+ } else {
+#ifdef AR1335_DEBUG
+ pr_info(" Get FW Version Success\n");
+#endif
+ break;
+ }
+ }
+
+ if(loop == 100) {
+ dev_err(
+ &client->dev,
+ "Couldn't get firmware version correctly after update (did the update fail?\n"
+ );
+ return -EINVAL;
+ }
+ }
+
+ }
+ else
+ {
+ static const char *const flash_error_message =
+ "Please connect only one camera and fix the MCU.\n"
+ "Hint: Connected only one camera? Is someone else using the "
+ "power down/reset GPIOs?\n";
+
+ /*
+ * When we do not have the reset GPIO, we cannot toggle it
+ * to make the MCU switch to firmware mode. So, we try getting
+ * the MCU into firmware assuming it is currently in
+ * bootloader mode.
+ *
+ * The following sequence is required for switching it to
+ * firmware mode.
+ */
+ int loop, get_firmware_version = 0;
+
+ /*
+ * We would have to verify that the MCU is in bootloader mode
+ * before sending the command to make it switch to firmware mode.
+ *
+ * So, we try to get the version of the bootloader.
+ */
+ for(loop = 0; loop < 10; loop++)
+ {
+ ret = mcu_bload_get_version(client);
+ if (ret < 0)
+ {
+ /* Trial and Error for 1 second (100ms * 10) */
+ msleep(100);
+ }
+ else
+ {
+ pr_info(" Get Bload Version Success\n");
+ break;
+ }
+ }
+
+ if(loop == 10)
+ {
+ dev_err(&client->dev, "couldn't get bootloader version\n");
+
+
+ get_firmware_version = 1;
+
+ msleep(1000);
+ }
+ else
+ {
+ /*
+ * We retry if we could boot into firmware mode as we're
+ * currently in bootloader mode (as mcu_bload_get_version
+ * succeeded).
+ */
+ ret = mcu_bload_go(client);
+ if (ret < 0) {
+ dev_err(&client->dev,"couldn't switch to firmware mode.\n");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+ else {
+ msleep(10);
+ get_firmware_version = 1;
+ }
+ }
+
+ /*
+ * We should verify if we have the version of the MCU we
+ * need. If not, we let the user know about it and exit
+ * the probe.
+ */
+ if (get_firmware_version)
+ {
+ ret = mcu_get_fw_version(client, fw_version_1335);
+ if (ret == 0)
+ {
+ ret = mcu_verify_fw_version(fw_version_1335);
+ }
+ else
+ {
+ dev_err(&client->dev, "couldn't get the MCU firmware version");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+
+ if (ret != 0)
+ {
+ dev_err(&client->dev, "wrong MCU firmware version");
+ dev_err(&client->dev, flash_error_message);
+ return -EINVAL;
+ }
+ }
+ }
+
+ dev_info(&client->dev, "Current Firmware Version - (%.32s)\n", fw_version_1335);
+
+ return 0;
+}
+
+static int ar1335_parse_and_get_clocks(struct device *dev)
+{
+ int retval = 0;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ ar1335_data.sensor_clk = devm_clk_get(dev, "xclk");
+ if (IS_ERR(ar1335_data.sensor_clk)) {
+ /* assuming clock enabled by default */
+ ar1335_data.sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(ar1335_data.sensor_clk);
+ }
+
+ /*mclk reserved for future use*/
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(ar1335_data.mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ /*mclk_source reserved for future use*/
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(ar1335_data.mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(ar1335_data.csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+
+ return 0;
+}
+
+static int ar1335_parse_and_get_gpios(struct device *dev)
+{
+ int err;
+ struct device_node *node = NULL;
+
+ if (dev == NULL)
+ {
+ dev_err(dev, "%s: Invalid device parameter\n", __func__);
+ return -EINVAL;
+ }
+
+ node = dev->of_node;
+
+ pwdn_gpio = of_get_named_gpio(node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwdn_gpio)) {
+ dev_err(dev, "no sensor pwdn pin available");
+ return -EINVAL;
+ }
+ else {
+#ifdef AR1335_DEBUG
+ printk("BOOT = %x \n", pwdn_gpio);
+#endif
+ }
+
+ reset_gpio = of_get_named_gpio(node, "rst-gpios", 0);
+ if (!gpio_is_valid(reset_gpio)) {
+ dev_err(dev, "no sensor reset pin available");
+ return -EINVAL;
+ }
+ else {
+#ifdef AR1335_DEBUG
+ printk("RESET = %x \n", reset_gpio);
+#endif
+ }
+
+ err = devm_gpio_request_one(dev, pwdn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ar1335_mipi_pwdn");
+ if (err < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ dev_warn(dev, "err = %d\n", err);
+ return err;
+ }
+
+ err = devm_gpio_request_one(dev, reset_gpio, GPIOF_OUT_INIT_HIGH,
+ "ar1335_mipi_reset");
+ if (err < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ dev_warn(dev, "err = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+/*!
+ * ar1335 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ar1335_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pinctrl *pinctrl;
+ struct device_node *node = client->dev.of_node;
+ struct device *dev = &client->dev;
+
+ int ret, frm_fmt_size = 0, i;
+ uint16_t sensor_id = 0;
+
+ if (!IS_ENABLED(CONFIG_OF) || !node)
+ return -EINVAL;
+
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(dev, "no pin available\n");
+
+ /* Set initial values for the sensor struct. */
+ memset(&ar1335_data, 0, sizeof(ar1335_data));
+
+ ret = ar1335_parse_and_get_gpios(dev);
+ if (ret)
+ {
+ pr_info("Warning: couldn't get GPIOs\n");
+ }
+
+ ret = ar1335_parse_and_get_clocks(dev);
+ if (ret)
+ {
+ dev_err(dev, "Error occurred when getting clock\n");
+ return ret;
+ }
+
+ clk_prepare_enable(ar1335_data.sensor_clk);
+
+ /*
+ * We usually get and set/enable regulators here. But it doesn't
+ * seem to be needed here as the Variscite EVK seems to be supplying
+ * the required voltage directly without us needing to set it.
+ */
+ toggle_gpio(reset_gpio, 1);
+ msleep(500);
+
+ ret = ar1335_verify_mcu(client);
+ if (ret)
+ {
+ dev_err(dev, "Error occurred when verifying MCU\n");
+ return ret;
+ }
+
+ ar1335_data.mipi_lane_config = 4;
+ ret = mcu_isp_configuration(CMD_ID_LANE_CONFIG, client);
+ if(ret)
+ {
+ dev_err(dev, "Error occurred in configuring mipi lanes\n");
+ return ret;
+ }
+
+ /*
+ * Query the number of controls from MCU
+ */
+ if (mcu_count_or_list_ctrls(client, NULL, &num_ctrls) < 0) {
+ dev_err(dev, "%s, Failed to get number of controls for sensor\n", __func__);
+ return -EFAULT;
+ }
+
+ /*
+ * Query the number for Formats available from MCU
+ */
+ if (mcu_count_or_list_fmts(client, NULL, &frm_fmt_size) < 0) {
+ dev_err(dev, "%s, Failed to get number of formats for sensor\n", __func__);
+ return -EFAULT;
+ }
+
+ /*
+ * Initialise the MCU related data as we're about to use them.
+ */
+ ret = mcu_data_init(dev, frm_fmt_size);
+ if (ret)
+ {
+ dev_err(dev, "%s: failed to initialize MCU related data\n", __func__);
+ return -EFAULT;
+ }
+
+ if (mcu_get_sensor_id(client, &sensor_id) < 0) {
+ dev_err(dev, "Unable to get MCU Sensor ID \n");
+ return -EFAULT;
+ }
+
+ if (mcu_isp_init(client) < 0) {
+ dev_err(dev, "Unable to INIT ISP \n");
+ return -EFAULT;
+ }
+
+ /*
+ * Enumerate the Formats in the sensor
+ */
+ if (mcu_count_or_list_fmts(client, stream_info, &frm_fmt_size) < 0) {
+ dev_err(dev, "Unable to enumerate the formats in the sensor\n");
+ return -EFAULT;
+ }
+
+ /*
+ * Fill some state information as required.
+ */
+ ar1335_data.i2c_client = client;
+
+ ar1335_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ ar1335_data.fmt.code = AR1335_DEFAULT_DATAFMT;
+ ar1335_data.fmt.colorspace = AR1335_DEFAULT_COLORSPACE;
+ ar1335_data.pix.width = AR1335_DEFAULT_WIDTH;
+ ar1335_data.pix.height = AR1335_DEFAULT_HEIGHT;
+ ar1335_data.streamcap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
+ ar1335_data.streamcap.capturemode = AR1335_DEFAULT_MODE;
+ ar1335_data.num_frm_fmts = frm_fmt_size;
+ ar1335_data.power_on = 0;
+
+ /*
+ * Configure the stream with default configuration
+ */
+ ret = ar1335_init(client);
+ if (ret)
+ {
+ dev_err(dev, "Failed to initialise the device with default configuration\n");
+ return ret;
+ }
+
+ v4l2_i2c_subdev_init(&ar1335_data.subdev, client, &ar1335_subdev_ops);
+
+ /*
+ * Initialize Controls by getting details about the controls from the MCU
+ */
+ ret = ar1335_ctrls_init(mcu_ctrl_info);
+ if (ret)
+ {
+ dev_warn(dev, "Failed to initialise the controls. Controls might not work\n");
+ }
+
+ /*
+ * Write default values for all controls
+ */
+ for (i = 0; i < num_ctrls; i++) {
+ if (mcu_ctrl_info[i].ctrl_type == CTRL_STANDARD) {
+ int ret;
+ struct v4l2_control ctrl = {
+ .id = mcu_ctrl_info[i].ctrl_id,
+ .value = mcu_ctrl_info[i].ctrl_data.std.ctrl_def
+ };
+
+ if (
+ mcu_ctrl_info[i].ctrl_id == 0x9a0926
+ )
+ {
+ /*
+ * We know that the MCU would fail when we
+ * try to write the V4L2_CID_ROI_EXPOSURE
+ * control as we are not in the correct auto
+ * exposure mode by default. So, skip it.
+ */
+ continue;
+ }
+
+ ret = ar1335_s_ctrl(&ar1335_data.subdev, &ctrl);
+ if (ret < 0)
+ {
+ dev_err(dev, "Failed to write default value for a control: %d; Control ID: %x\n", i, mcu_ctrl_info[i].ctrl_id);
+ }
+ }
+ }
+
+ ar1335_data.subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ar1335_data.subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ar1335_data.pads[0].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&ar1335_data.subdev.entity, 1, ar1335_data.pads);
+ ar1335_data.subdev.entity.ops = &ar1335_sd_media_ops;
+ if (ret < 0) {
+ dev_err(dev, "Failed to init media entity pads\n");
+ return ret;
+ }
+
+ ret = v4l2_async_register_subdev(&ar1335_data.subdev);
+ if (ret)
+ {
+ dev_err(dev, "Failed to register the I2C subdev for the sensor\n");
+ return ret;
+ }
+
+ pr_info("AR1335 detected.\n");
+
+ return 0;
+}
+
+/*!
+ * ar1335 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ar1335_remove(struct i2c_client *client)
+{
+ v4l2_async_unregister_subdev(&ar1335_data.subdev);
+
+ clk_disable_unprepare(ar1335_data.sensor_clk);
+
+ /*
+ * Power down the MCU
+ */
+ if (reset_gpio >= 0)
+ {
+ toggle_gpio(reset_gpio, 0);
+ }
+
+ /*
+ * Free up the GPIOs
+ */
+ if (pwdn_gpio >= 0)
+ devm_gpio_free(&client->dev, pwdn_gpio);
+
+ if (reset_gpio >= 0)
+ devm_gpio_free(&client->dev, reset_gpio);
+
+ return 0;
+}
+
+static const struct i2c_device_id ar1335_id[] = {
+ {"ar1335", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ar1335_id);
+
+static struct i2c_driver ar1335_i2c_driver = {
+ .driver = {
+ .name = "ar1335",
+ .owner = THIS_MODULE
+ },
+ .probe = ar1335_probe,
+ .remove = ar1335_remove,
+ .id_table = ar1335_id,
+};
+
+
+module_i2c_driver(ar1335_i2c_driver);
+
+MODULE_DESCRIPTION("AR1335 V4L2 driver");
+MODULE_AUTHOR("e-con Systems");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/imx8/ar1335.h b/drivers/media/platform/imx8/ar1335.h
new file mode 100644
index 000000000000..d7d5dc094e0e
--- /dev/null
+++ b/drivers/media/platform/imx8/ar1335.h
@@ -0,0 +1,291 @@
+/*
+ * ar1335.h - ar1335 sensor mode tables
+ *
+ * Copyright (c) 2018-2019, e-con Systems, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 __AR1335_TABLES__
+#define __AR1335_TABLES__
+
+#define AR1335_XCLK_MIN 6000000
+#define AR1335_XCLK_MAX 24000000
+
+#define ar1335_reg struct reg_16
+#define AR1335_TABLE_WAIT_MS 0
+#define AR1335_TABLE_END 1
+#define AR1335_WAIT_MS 10
+#define AR1335_DEFAULT_MODE 0
+
+#define AR1335_DEFAULT_WIDTH 640
+#define AR1335_DEFAULT_HEIGHT 480
+
+#define AR1335_MAX_FORMAT_SUPPORTED 1
+
+#define AR1335_DEFAULT_FPS 120
+
+#define AR1335_DEFAULT_DATAFMT MEDIA_BUS_FMT_UYVY8_2X8
+#define AR1335_DEFAULT_COLORSPACE V4L2_COLORSPACE_SRGB
+
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
+/* Defines related to MCU */
+
+#define CMD_SIGNATURE 0x43
+#define TX_LEN_PKT 5
+#define RX_LEN_PKT 6
+#define HEADER_FOOTER_SIZE 4
+#define CMD_STATUS_MSG_LEN 7
+
+#define VERSION_SIZE 32
+#define VERSION_FILE_OFFSET 100
+
+#define MCU_CMD_STATUS_SUCCESS 0x0000
+#define MCU_CMD_STATUS_PENDING 0xF000
+#define MCU_CMD_STATUS_ISP_PWDN 0x0FF0
+#define MCU_CMD_STATUS_ISP_UNINIT 0x0FF1
+
+#define MAX_NUM_FRATES 10
+#define MAX_CTRL_DATA_LEN 100
+#define MAX_CTRL_UI_STRING_LEN 32
+
+typedef enum _errno {
+ ERRCODE_SUCCESS = 0x00,
+ ERRCODE_BUSY = 0x01,
+ ERRCODE_INVAL = 0x02,
+ ERRCODE_PERM = 0x03,
+ ERRCODE_NODEV = 0x04,
+ ERRCODE_IO = 0x05,
+ ERRCODE_HW_SPEC = 0x06,
+ ERRCODE_AGAIN = 0x07,
+ ERRCODE_ALREADY = 0x08,
+ ERRCODE_NOTIMPL = 0x09,
+ ERRCODE_RANGE = 0x0A,
+
+ /* Reserved 0x0B - 0xFE */
+
+ ERRCODE_UNKNOWN = 0xFF,
+} RETCODE;
+
+typedef enum _cmd_id {
+ CMD_ID_VERSION = 0x00,
+ CMD_ID_GET_SENSOR_ID = 0x01,
+ CMD_ID_GET_STREAM_INFO = 0x02,
+ CMD_ID_GET_CTRL_INFO = 0x03,
+ CMD_ID_INIT_CAM = 0x04,
+ CMD_ID_GET_STATUS = 0x05,
+ CMD_ID_DE_INIT_CAM = 0x06,
+ CMD_ID_STREAM_ON = 0x07,
+ CMD_ID_STREAM_OFF = 0x08,
+ CMD_ID_STREAM_CONFIG = 0x09,
+ CMD_ID_GET_CTRL_UI_INFO = 0x0A,
+
+ /* Reserved 0x0B to 0x0F */
+
+ CMD_ID_GET_CTRL = 0x10,
+ CMD_ID_SET_CTRL = 0x11,
+
+ /* Reserved 0x12, 0x13 */
+
+ CMD_ID_FW_UPDT = 0x14,
+ CMD_ID_ISP_PDOWN = 0x15,
+ CMD_ID_ISP_PUP = 0x16,
+
+ /* Reserved - 0x17 to 0xFE (except 0x43) */
+ CMD_ID_LANE_CONFIG = 0x17,
+ CMD_ID_MIPI_CLK_CONFIG = 0x18,
+
+ CMD_ID_UNKNOWN = 0xFF,
+
+} HOST_CMD_ID;
+
+enum {
+ FRAME_RATE_DISCRETE = 0x01,
+ FRAME_RATE_CONTINOUS = 0x02,
+};
+
+enum {
+ CTRL_STANDARD = 0x01,
+ CTRL_EXTENDED = 0x02,
+};
+
+enum {
+/* 0x01 - Integer (32bit)
+ 0x02 - Long Int (64 bit)
+ 0x03 - String
+ 0x04 - Pointer to a 1-Byte Array
+ 0x05 - Pointer to a 2-Byte Array
+ 0x06 - Pointer to a 4-Byte Array
+ 0x07 - Pointer to Generic Data (custom Array)
+*/
+
+ EXT_CTRL_TYPE_INTEGER = 0x01,
+ EXT_CTRL_TYPE_LONG = 0x02,
+ EXT_CTRL_TYPE_STRING = 0x03,
+ EXT_CTRL_TYPE_PTR8 = 0x04,
+ EXT_CTRL_TYPE_PTR16 = 0x05,
+ EXT_CTRL_TYPE_PTR32 = 0x06,
+ EXT_CTRL_TYPE_VOID = 0x07,
+};
+
+/* Stream and Control Info Struct */
+typedef struct _isp_stream_info {
+ uint32_t fmt_fourcc;
+ uint16_t width;
+ uint16_t height;
+ uint8_t frame_rate_type;
+ union {
+ struct {
+ uint16_t frame_rate_num;
+ uint16_t frame_rate_denom;
+ } disc;
+ struct {
+ uint16_t frame_rate_min_num;
+ uint16_t frame_rate_min_denom;
+ uint16_t frame_rate_max_num;
+ uint16_t frame_rate_max_denom;
+ uint16_t frame_rate_step_num;
+ uint16_t frame_rate_step_denom;
+ } cont;
+ } frame_rate;
+} ISP_STREAM_INFO;
+
+
+typedef struct _isp_ctrl_ui_info {
+ struct {
+ char ctrl_name[MAX_CTRL_UI_STRING_LEN];
+ uint8_t ctrl_ui_type;
+ uint8_t ctrl_ui_flags;
+ } ctrl_ui_info;
+
+ /* This Struct is valid only if ctrl_ui_type = 0x03 */
+ struct {
+ uint8_t num_menu_elem;
+ char **menu;
+ } ctrl_menu_info;
+} ISP_CTRL_UI_INFO;
+
+typedef struct _isp_ctrl_info_std {
+ uint32_t ctrl_id;
+ uint8_t ctrl_type;
+ uint8_t mcu_ctrl_index;
+ union {
+ struct {
+ int32_t ctrl_min;
+ int32_t ctrl_max;
+ int32_t ctrl_def;
+ int32_t ctrl_step;
+ } std;
+ struct {
+ uint8_t val_type;
+ uint32_t val_length;
+ // This size may vary according to ctrl types
+ uint8_t val_data[MAX_CTRL_DATA_LEN];
+ } ext;
+ } ctrl_data;
+ ISP_CTRL_UI_INFO ctrl_ui_data;
+} ISP_CTRL_INFO;
+
+struct ar1335 {
+ int numctrls;
+ struct v4l2_subdev subdev;
+ struct i2c_client *i2c_client;
+ uint16_t frate_index;
+ struct media_pad pads[1];
+
+ u32 mclk;
+ u8 mclk_source;
+ struct clk *sensor_clk;
+
+ int csi;
+
+ /*
+ * Format related data
+ */
+ struct v4l2_pix_format pix;
+
+ struct ar1335_datafmt {
+ u32 code;
+ enum v4l2_colorspace colorspace;
+ } fmt;
+
+ struct v4l2_captureparm streamcap;
+
+ bool on;
+
+ int num_frm_fmts;
+
+ /*
+ * Array of Camera framesizes
+ *
+ * Moved from global
+ */
+ struct mcu_frmfmt {
+ struct v4l2_frmsize_discrete size;
+ unsigned int * framerates;
+ int num_framerates;
+ int mode;
+ } *mcu_cam_frmfmt;
+
+ int power_on;
+
+ uint16_t mipi_lane_config;
+ uint16_t mipi_clk_config;
+
+ struct v4l2_ctrl *ctrls[];
+
+};
+
+static ISP_STREAM_INFO *stream_info = NULL;
+static ISP_CTRL_INFO *mcu_ctrl_info = NULL;
+
+/* Total formats */
+static int num_ctrls = 0;
+static int *streamdb;
+static uint32_t *ctrldb;
+
+/* Mutex for I2C lock */
+DEFINE_MUTEX(mcu_i2c_mutex_1335);
+
+static int ar1335_read(struct i2c_client *client, u8 * val, u32 count);
+static int ar1335_write(struct i2c_client *client, u8 * val, u32 count);
+static int ar1335_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
+static int ar1335_s_power(struct v4l2_subdev *sd, int on);
+
+/*
+ * MCU related functions
+ */
+static int mcu_get_fw_version(struct i2c_client *client, unsigned char * fw_version);
+static int mcu_verify_fw_version(const unsigned char *const fw_version);
+static int mcu_count_or_list_fmts(struct i2c_client *client, ISP_STREAM_INFO *stream_info, int *frm_fmt_size);
+static int mcu_count_or_list_ctrls(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ctrl_info, int *numctrls);
+static int mcu_get_sensor_id(struct i2c_client *client, uint16_t * sensor_id);
+static int mcu_get_cmd_status(struct i2c_client *client, uint8_t * cmd_id,
+ uint16_t * cmd_status, uint8_t * ret_code);
+static int mcu_isp_init(struct i2c_client *client);
+static int mcu_stream_config(struct i2c_client *client, uint32_t format,
+ int mode, int frate_index);
+static int mcu_set_ctrl(struct i2c_client *client, uint32_t ctrl_id,
+ uint8_t ctrl_type, int32_t curr_val);
+static int mcu_get_ctrl(struct i2c_client *client, uint32_t ctrl_id,
+ uint8_t * ctrl_type, int32_t * curr_val);
+static int mcu_get_ctrl_ui(struct i2c_client *client,
+ ISP_CTRL_INFO * mcu_ui_info, int index);
+static int mcu_fw_update(struct i2c_client *client, unsigned char *txt_fw_version);
+static int mcu_isp_power_down(struct i2c_client *client);
+static int mcu_isp_power_wakeup(struct i2c_client *client);
+
+#endif /* __AR1335_TABLES__ */
diff --git a/drivers/media/platform/imx8/ecam131_mcu_fw.txt b/drivers/media/platform/imx8/ecam131_mcu_fw.txt
new file mode 100644
index 000000000000..ef3fee7ab348
--- /dev/null
+++ b/drivers/media/platform/imx8/ecam131_mcu_fw.txt
@@ -0,0 +1,2129 @@
+":020000040800F2\n"
+":40040000D83100204D050008D9400008CF290008000000000000000000000000000000000000000000000000000000001744000800000000000000000B05000889450008C7\n"
+":40044000A94C00085F0500085F050008410900085F0500085F0500085F050008FD080008000000005F0500085F0500085F0500085F0500085F0500085F05000879460008B5\n"
+":40048000894600085F0500085F050008000000005F050008F52900085F050008D12900085F050008554300085F0500085F050008994C00085F050008000000000000000050\n"
+":4004C0000348854600F0FAF800480047C1720008D8310020084B19680868203080F30988022080F31488BFF36F8F3FBCAE4608BC04BC62B6184700000C000020EFF3108010\n"
+":4005000072B6704780F310887047EFF309800E4B1A6820381060F0C044464D4656465F46F0C008B572B607F00FFF62B60CBC116808681030F0C8A046A946B246BB4680F362\n"
+":4005400009882038F0C818470C0000200448804704480047FEE7FEE7FEE7FEE7FEE7FEE725460008C104000830B50B46014600202022012409E00D46D5409D4205D31D469C\n"
+":400580009540491B2546954040191546521E002DF1DC30BD70B500242546002801DA01244042002901DA01254942FFF7DDFFAC4200D04042002C00D0494270BDF0B51FB466\n"
+":4005C0000646002082B005464024019100901BE0019922460F46304600F05EF8049A059B801A994110D310461946224600F044F8361A8F410197224601200021009F00F0AF\n"
+":400600003BF838184D4100902046641E0028DFDC019B00982946324607B0F0BD03460B439B0703D009E008C9121F08C0042AFAD203E00B780370401C491C521EF9D270478A\n"
+":40064000D2B201E00270401C491EFBD270470022F6E710B513460A4604461946FFF7F0FF204610BD0321001D401E037812021A43491EF9D51046704710B5202A04DB01462C\n"
+":40068000203A9140002010BD914020239C1A0346E3401943904010BD10B5202A04DB0846203AD040002110BD0B46D340D0402024A21A91400843194610BD0000064C01252B\n"
+":4006C000064E05E0E36807CC2B430C3C98471034B442F7D3FFF7F8FE6C1202088C12020810B5364CE069000267D4A069C007FCD16368334A334934A004F0DEFA6068C00791\n"
+":4007000004D03C48E0603C48E06005E02C4A2D49921D3AA004F0D0FA6368294A29490A3241A004F0C9FAA069C007FCD16368244A2449143224A004F0BFFA6068C00704D064\n"
+":40074000292252011F4944A00BE06068400704D54A4860614A48606105E0194A19491C3248A004F0A9FA6368154A164922322EA004F0A2FA4E49042003F0E0FC104A114926\n"
+":4007800026324CA004F098FAE2690120C005E16902434DA004F090FA094A0A49283245A004F08AFA60680121890408436060044A04492C323FA004F07FFA10BD00200240F1\n"
+":4007C00001050000638C0008202D2D2D2025732825642920464C4153482D3E50454352203D2030782530387820202D2D2D200A0D00000000EFCDAB8905040302202D2D2DD3\n"
+":40080000202573282564292050454B45595220556E6C6F636B656420416C7265616479202D2D2D200A0D0000202D2D2D20257328256429204E6F772C20464C4153482D3E6F\n"
+":4008400050454352203D20307825303878202D2D2D200A0D00000000202D2D2D202573282564292050454C4F434B204C6F636B6564202D2D2D200A0D00000000C8D9EAFB59\n"
+":4008800027262524202D2D2D20257328256429204F50544C4F434B20416C726561647920556E6C6F636B6564202D2D2D200A0D00F0800000202D2D2D20257328256429204F\n"
+":4008C0002D2D2D200A0D00002056616C20416674657220556E6C6F636B204F7074696F6E204279746573202E2E2E2030782530387820307825303878200A0D0010B5012038\n"
+":40090000800200F0FBF910BD04A004F0D5F97D24E400204606F088FDFBE7000020556E7265636F76657261626C65204572726F72204F636375726564202121200A0D0000C1\n"
+":4009400010B500F02DF910BD10B5084900224A6107494B684C1523434B604B68082423434B60C009C001026010BD0000A40000200020024010B5214A00219069C30520482E\n"
+":4009800004D54169022319434161911593699B0505D543690124234343616302194393695B0505D54369082423434361E301194393691B0505D54369042423434361630248\n"
+":4009C000194393699B0405D543691024234343616302194393699B0304D5446920231C43446119439369DB0305D54369402423434361A0020143916110BD000000200240E3\n"
+":400A0000A400002008B517A004F056F900F042F91C48416842151143416041680822114341600021130619608169C907FCD18169890714D50221816141684122D20091439B\n"
+":400A4000416018680090104A104911A004F034F91EA004F031F900F011F903F061FBFFF753FF000020466C6173682045726173652042414E4B312053746172742021212098\n"
+":400A80000A0D000000200240BB040000448C0008202D2D2D20204166746572202573282564292041742041646472657373203078253038782056616C7565203D20307825CC\n"
+":400AC000303878202D2D2D200A0D000020466C6173682045726173652042414E4B312053756363657373202121200A0D0000000070B50024024620325179022903D004214B\n"
+":400B0000C16301243CE001680B680E25AB430B6001680B685B085B000B601A4B0168994201D1012121E0174B1433994201D110211BE0144B2833994201D1891515E0114B6D\n"
+":400B40003C33994201D189140FE00E4B5033994202D10121090408E00A4B6433994202D10121090501E001210906064B083B59600121517100211171816B002900D08847C8\n"
+":400B8000204670BD0800024031B500F095F9044600F092F90099001B8842F9D338BD7047F8B5344CA0690026C005334D002811DBA06980050ED4A06940050BD4A0690005D9\n"
+":400BC00008D4A069800405D4A069800302D4A069C00309D5287801282BD0AF68FFF7CAFE384600F055F82E70A069800712D50220A061287800280DD0287801281ED06068F7\n"
+":400C0000082188436060A868FFF7C9FF0020C043A8602E70287800280AD160684121C90088436060606803210904884360602E74F8BDEF680020C043E860CFE76868401EC7\n"
+":400C40006860686800280DD0E868FFF7A8FFE8688030E86061680122520291436160FFF773FED7E70020C043E8602E70FFF797FFD0E7000000200240A40000200348416842\n"
+":400C800002221143416000207047000000200240704700000948416889070CD54168C90703D00749C1600749C160074901610749016100207047012070470000002002401D\n"
+":400CC000EFCDAB8905040302BFAE9D8C1615141310B501218902884204D1034A034904A003F0EAFF10BD0000270400002D8C00082025732028256429200A0D0010B5044930\n"
+":400D00004A69024202D04861FFF7E2FF10BD000000040140F8B500230124A7E027469F403A4070D04D68022D01D0122D14D1DD08AD002D1800952D6A5E07AC46F50E0F266B\n"
+":400D4000AE46AE406546B543AC460E697546AE4065462E43009D2E624D68012D05D0022D03D0112D01D0122D16D185680326AC465D00AE46AE406546B543AC46CE687546D7\n"
+":400D8000AE4065462E43866046680D79BE43ED06ED0F9D403543456006685F000325BD40AE46AE430D79B446AE07B60FBE4065462E430660C6687546AE438D68BD40354390\n"
+":400DC000C5604D68ED0050D52B4D6E6B26436E639E082A4DB6007519AC46AD689E07360F0F27B740BD4305273F07B84201D100271AE0234FB84201D1012715E0214FB842D9\n"
+":400E000002D1022710E030E01F4FB84201D103270AE01E4FB84201D1042705E01C4FB84201D1052700E00627B7402F436546AF60184D2E684F689643FF0300D516432E6043\n"
+":400E40006E684F689643BF0300D516436E60AE684F689643FF0200D51643AE60EE684F689643BF0200D51643EE605B1C0A681546DD4000D052E7F8BD001002400000014096\n"
+":400E80000004005000080050000C005000100050001C0050000401400069084000D00120704742694A4042617047002A01D08161704781627047000001480068704700009B\n"
+":400EC0000400002070B5024640325378202B1CD11378012B19D00123137024245470046825689D432560046825681E03B5432560046825680D432560006801681943016048\n"
+":400F0000202050700020107070BD022070BD70B5024640325378202B1BD11378012B18D0012414702423537003681D68A5431D6005682B680F263602B343090219432960BA\n"
+":400F40000068016821430160202050700020107070BD022070BD000010B5034A034904A003F0AAFE10BD000021040000138C00082025732028256429200A0D0010B5034A8E\n"
+":400F8000034904A003F098FE10BD00000D040000AF8B00082025732028256429200A0D0070B503689A691968D40507D50C0605D5446C01252C4344642C02DC61530508D56D\n"
+":400FC0000B0606D5436C082423434364E3010468E361920508D5090606D5416C02221143416411020268D161416C0B22114202D0416C01F0D5FD70BD026891691268436B8A\n"
+":40100000002B00D01847704770B5054600681449144C884213D1284600F054F80346124A124913A003F048FE6078042803D0A07860700420A07003F057F900206864184943\n"
+":40104000286888420BD1284600F03CF8064A03460F32064913A003F02FFE0320207070BD0054004060000020F6030000998B000820257328256429202D2048414C5F4932E5\n"
+":40108000435F4572726F7243616C6C6261636B20202D20307825303878200A0D0000000000780040202573202825642920457272436F6465203D20307825303878200A0D77\n"
+":4010C00000000000406C704770B5040006D02546403568780026002802D005E0012070BD2E70204600F06EF924206870206801684908490001600F216068090688432168BD\n"
+":40110000086121688A680120C00382438A60E1680129A16808D021229202114322689160E168022902D005E00143F7E701212268C902516021684A680F4B1A434A602168A4\n"
+":40114000CA688243CA60616920690843A169090208432168C860216AE069084321680860206801680122114301606664202068702663AE70002070BD0080000210B5034A5C\n"
+":40118000034904A003F098FD10BD000012040000C48B00082025732028256429200A0D0000680649884205D105480178092902D00321017070470B21FBE700000078004061\n"
+":4011C0009000002000680649884205D105480178052902D00321017070470721FBE700000078004090000020F8B50546044640356878202830D120688069C04300042BD50C\n"
+":401200002878012828D001202870222068701020A87000266664626263851048E06210486063608DFF2804D9FF20012320851B0603E0608D012320855B0609208002009052\n"
+":40124000208DC2B2204602F043F82E700221204601F026FC0020F8BD0220F8BD0000FFFF21300008FFB5054604464035687881B020287ED1287801287BD001202870FFF754\n"
+":401280001BFE0746012200901923D103204602F031F800283FD1212068701020A8700026666403986062049860856663618D01204003FF2903D9FF222285009034E0618DA4\n"
+":4012C0002185009036E02046029902F001F836E002F05BF8002803D0606C042847D01AE0606A411C6162017820688162608D401E6085208D401E0004000C20851FD1608DBC\n"
+":4013000000281CD000970022802120460A9B01F0F1FF002802D0032005B0F0BD608DFF2805D9FF222285009601231B06CBE7608D20850096208D0123C2B25B06C3E7608D28\n"
+":401340000A9900283A462046C2D101F0F7FF0028C2D121682020C86121684A68064B1A404A606870AE702E700020D5E701E00120D2E70220D0E7000000E800FE10B5034A09\n"
+":40138000034904A003F098FC10BD00001C040000F98B00082025732028256429200A0D0010B5034A034904A003F086FC10BD000017040000DF8B00082025732028256429D1\n"
+":4013C000200A0D00F0B5234A0168122403200125214E85B0914215D1C02100910021029103900194049569461C48FFF793FCB06B69050843B06300220321172000F058F93B\n"
+":40140000172022E0164A914221D189156A4632C20320072781C2052069460007FFF77AFC1020694631C103200390694604970B48FFF770FCB06B012189070843B06300225E\n"
+":401440000321152000F034F9152000F027F905B0F0BD00000054004000100240000400500078004038B500680D49884213D10D4CA3780A2B10D0A08900900B4A0B490C48C5\n"
+":4014800003F01AFC6078042803D0A07860700420A07002F029FF38BD63700C20A07038BD0054004060000020D30300007D8B0008F00F020838B500680E49884214D10E4C65\n"
+":4014C000A378062B11D0A089ED22009092000B490B4803F0F1FB6078042803D0A07860700420A07002F000FF38BD63700820A07038BD00000054004060000020618B0008FE\n"
+":4015000058100208F8B5034640335C78202C1ED11C78012C1BD001241C7022245C7020249C700024446405686E680127FF03BE436E6041624285418D01850649C16206497B\n"
+":4015400041631C701F2101F0ABFA0020F8BD0220F8BD00000000FFFFB1310008F8B5034640335C78202C1ED11C78012C1BD001241C7021245C7020249C7000244464056862\n"
+":401580006E680127FF03BE436E6041624285418D01850649C162064941631C70172101F07FFA0020F8BD0220F8BD00000000FFFFB131000802480168491C01607047000047\n"
+":4015C0000400002010B506480168402211430160002000F007F800F03DF8002010BD00000020024000B5014687B00022102000F05FF8102000F052F81148816B02221143BE\n"
+":40160000816305A9684600F071FA00F095FA0D49FEF7AAFF0D490C4A0A600D4A401ECA604860002008618860084600F093FE002802D0012007B000BD044800F0A6FEF9E770\n"
+":401640000010024040420F0000040040D8180020E703000010B51048416B012211434163816B02041143816300221146501F00F01FF803210022481F00F01AF80321002257\n"
+":40168000081F00F015F803210022084600F010F8032000F003F810BD00100240C106C90E01208840014908607047000000E100E010B502F013FD10BDF8B54E490746012551\n"
+":4016C0000020ED034A4B4B4A4031082F7BD00EDC012F48D0022F60D0042F22D1CC680326B602344065D07F02BC424ED064E0102F77D00126032436042404202F09D0FF3FC9\n"
+":40170000012F0ED1C968214053D07400A1423CD06BE00B6909692140B14203D199052EE02846F8BD01256D04A94203D19907F8D53148F8BDA142FCD111688903F9D511686D\n"
+":4017400003200005014001200005091A09D0091A05D0814201D12948F8BD2948F8BD2948F8BD2948F8BDCC68A407A40F0AD0022C0BD0012C0ED0032CF4D10969890500291C\n"
+":40178000CEDBF8BD00F0E8F9F8BD11684907FBD51846F8BD00F0F0F9F8BDCC680C26344007D0082CF1D0042CF4D00C2CE5D0F8BD09E000F0C1F9FAE7012292029442E9D015\n"
+":4017C000B442DAD0F3E7C968032424032140F0D001256D036C10A942D7D0A142DAD0E6E7FFE7916B4902E4D4E1E7B142D2D0DEE70024F400001002408890000020A1070080\n"
+":4018000000093D0040420F0080841E00F8B504460078594D800672D5574E0027403EB06BC00004D4B06BA9050843B063012753480168C90511D40168821511430160FFF71F\n"
+":401840003BFB009005E0FFF737FB0099401A642837D84A480068C005F5D532680321090560680A400140914208D08103890F032904D13168890301D50120F8BD2A6903210F\n"
+":4018800009040A4022D0084090421FD0207880061CD528692A6988430121C9040A432A612A698A432A612861C0050FD5FFF704FB009008E0FFF700FB0099411A3048814267\n"
+":4018C00001D90320F8BD28698005F3D561688803800F032805D132680005824301400A4332602869032261681204114008432861002F04D0B16B012000078143B16320787F\n"
+":40190000C00705D0E868A168800880000843E8602078800705D5E8680C218843E1680843E8602078400706D5E86803218902884321690843E8602078000706D5E86803216B\n"
+":401940000903884361690843E8602088C00506D5E868032109048843A1690843E8602078000606D5E868032189048843E1690843E8600020F8BD00004010024000700040C9\n"
+":4019800088130000F8B5054653480E460068C007C00FB0420AD25048016849084900314301600068C007C00FB0426FD128784B4C800705D5E068F0218843A9680843E060E1\n"
+":4019C0002878C00752D06868022817D0032818D02168012818D08905002957DAE168890889000143E160FFF767FA69680746022912D003291CD0012926D033E0216889031E\n"
+":401A0000EAE721688901E7E74907E5E7FFF754FAC11B3348814223D8E0680007800F0228F4D123E0FFF748FAC11B2D48814217D8E0680007800F0328F4D117E0FFF73CFA83\n"
+":401A4000C11B274881420BD8E0680007800F0128F4D10BE0FFF730FAC11B2148814201D90320F8BDE0680007800FF3D11A480168C907C90FB1420BD9016849084900314381\n"
+":401A800001600068C007C00FB04201D00120F8BD2878400706D5E068072109028843E9680843E0602878000707D5E0680721C90288432969C9000843E06000F05DF8E1684D\n"
+":401AC000084A0906090F515CC840074908600020FFF788FD0020F8BD002002400010024088130000FC8A00080000002010B50F2202600C4AD3689B079B0F4360D368F0246C\n"
+":401B000023408360D46807231B021C40C460D268D2081A40026104480068C007C00F086010BD00000010024000200240014800687047000000000020044805490068C9689D\n"
+":401B4000044A4905490F515CC84070470000002000100240158B0008044805490068C968044A8904490F515CC84070470000002000100240158B000810B5184AD1680C2073\n"
+":401B8000084004280BD0082810D00C2810D050680004410F0120C003491C884010BD1068C00601D50E4810BD0E4810BD0E4810BD88020E4B000F185C0902D368890F491CA2\n"
+":401BC000DB0301D5084A05E01268D20601D5044A00E0044A5043FEF7C7FC10BD0010024000093D000024F40000127A000C8B0008F8B504460078F24DC0074AD0E86800077D\n"
+":401C0000800F022807D0E8680007800F032809D1E868C00306D5286880033AD56068002873D036E0012062680004824203D129680143296011E0052301211B0489049A4228\n"
+":401C40002A6802D10A432A60F1E782432A602A6802400092286888432860606800280CD0FFF72AF9064604E0FFF726F9801B64287ED828688003F7D50BE0FFF71DF90646EF\n"
+":401C800004E0FFF719F9801B6428F1D828688003F7D42078800741D5E8681F270007800F3F02012807D0E8680007800F032809D1E868C00306D42868400717D5E0680128BC\n"
+":401CC00023D113E0E068002817D029680922914301432960FFF7F0F8064604E0FFF7ECF8801B0228C4D828684007F7D568682169B84309020843686010E0286840084000E2\n"
+":401D00002860FFF7D9F8064605E090E0FFF7D4F8801B0228ACD828684007F7D42078C00676D5E868A74E0007800F0BD0A06900285DD02868FF21013108432860FFF7BCF8EA\n"
+":401D4000074644E02868800502D5A06900286ED0206A69683140884212D902F08DFA0028AED16868216AB04308436860686800E0BBE00002217F000A0906084368600FE08D\n"
+":401D80006968B143014369606868217F0002000A090608436860206A02F06EFA00288FD1206A410B0120C003491C8840E96809060A0F8549895CC840844908600020FFF7E1\n"
+":401DC00011FC25E0FFF778F8C01B02288AD828688005F7D56868216AB043084368606868217F0002000A09060843686010E02968FF20013081432960FFF75EF8064604E08A\n"
+":401E0000FFF75AF8801B02286FD828688005F7D420786F4E000723D560690028306910D0012108433061FFF747F8074605E0C5E0FFF742F8C01B022857D830698007F7D556\n"
+":401E40000EE0400840003061FFF736F8074604E0FFF732F8C01B022847D830698007F7D42078400762D5A86B0027C00005D4A86B012109070843A863012756480168C90556\n"
+":401E800011D40168821511430160FFF715F8009005E0FFF711F80099401A642825D84D480068C005F5D5FF20A2680130824203D131690143316111E001218902002A07D008\n"
+":401EC00005231B029A4203D132690A433261EFE7326982433261306988433061A06800280FD0FEF7E9FF009007E060E0FEF7E4FF0099411A3848814259D830698005F5D5E9\n"
+":401F00000DE0FEF7D9FF009006E0FEF7D5FF0099411A314881424AD830698005F5D4002F04D0A96B012000078143A963606A002842D0E9680907890F03293FD001263606C5\n"
+":401F40000228286805D0B0432860FEF7B5FF04462FE0B0432860FEF7AFFF074604E0FEF7ABFFC01B022822D828688001F7D4E16AA06AEA680843216BFD231B049A4311439E\n"
+":401F80000843E860286830432860FEF795FF044604E0FEF791FF001B022808D828688001F7D509E0FEF788FF001B022801D90320F8BD28688001F5D40020F8BD0120F8BDE4\n"
+":401FC0000010024000E00000FC8A000800000020401002400070004088130000704738B501684A68D243520609D48A68D243D20705D18A68D243520601D5816C08E04A68A9\n"
+":40200000D243120606D48A68D243920702D4C16C884738BD4A68D2439206FAD48A68D243D20606D4426D02231A4342651022D2438A6001688A680123D2439206002A08DB0A\n"
+":40204000426D1A4342658A6800920A684024A2430A6001688A68D243540602464032002C09DB547C122C06D0446D04252C434465CC688C6800948C68E443E40505D4446D50\n"
+":4020800008252C4344658C680094446D002CC0D04C68E025AC434C605374FFF79FFF38BD70B5040006D025464035687C0026002802D005E0012070BD2E74204600F032F80A\n"
+":4020C0000220687420680168402291430160A168606822690843E16811430843616901220843A169520211400843E1690843216A0843A16A084321680860A0690421000CAD\n"
+":402100000840616A0843216848602168E06A08612068C16992009143C161666501206874002070BD00B50068104985B088421AD10F48416B821411434163A0200090022022\n"
+":40214000019000210320039002910491052069460007FEF7DFFD002203211920FFF7A8FA1920FFF79BFA05B000BD00000030014000100240FFB5054604464035687C81B040\n"
+":40218000012872D100293CD0002A3AD0287C01286BD00120287412206874002666652163A286E286E664A664A663A687E6870127A06A7F03B84207D120680168B9430160A7\n"
+":4021C00020680168394301600121A068C903884205D120680168012292031143016020680168490603D40168402211430160E0680028606808D0002820D0E08E01281DD0DA\n"
+":4022000026E0012005B0F0BD002802D0E08E012808D1206B411C216321680078C860E08E401EE086E08E002820D0002202212046049B02F097F8002815D1EAE7206B2168A0\n"
+":402240000088C860206B801C2063E08E401EE086E08E00280AD0002202212046049B02F081F80028EAD00320CCE729E0A06AB84205D1216808680122120310430860002204\n"
+":4022800002212046049B02F06DF82027002807D1012280212046049B02F064F8002803D0606D38436065DEE7A068002803D12068C16880680090012068742E740020A1E700\n"
+":4022C00002209FE7042204490428086902D09043086170471043FBE700E000E0094910B5401E884201D9012010BD074C60610321081F01F0F3FE0020A0610720206100203B\n"
+":4023000010BD0000FFFFFF0000E000E070B502462032137D012B1BD00123137502245475046865687026B5436560046865680E68354365600468A5688026B543A560006816\n"
+":40234000846849680C43846053750020107570BD022070BD70B5040005D025462035687D002802D006E0012070BD00202875204600F00AF802206875211D206802F08CF982\n"
+":4023800001206875002070BD70470268D36801210B43D360006802680A43026000207047704770B50446006801690025C9438907002915DBC168C943890711D4E91E016196\n"
+":4023C00001202075206880698007204602D0FFF7E7FF04E000F08EF8204600F025F9257520680169C943490717D4C168C943490713D40421C9430161022020752068806953\n"
+":402400008005800F204602D0FFF7CAFF04E000F071F8204600F008F9257520680169C943090716D4C168C943090712D40821C9430161042020752068C0698007204602D080\n"
+":40244000FFF7AEFF04E000F055F8204600F0ECF8257520680169C943C90617D4C168C943C90613D41021C9430161082020752068C0698005800F204602D0FFF791FF04E05E\n"
+":4024800000F038F8204600F0CFF8257520680169C943C90708D1C168C943C90704D1891E0161204600F0C2F820680169C943490609D4C168C943490605D44021C943016155\n"
+":4024C000204600F0BDF870BD00B500680121890785B088420CD101200090002002210290039001910491052069460007FEF712FC05B000BD7047F8B5064604462036307D6C\n"
+":402500000D4601280DD001203075022070750427002A08D0042A16D0082A2AD00C2A4DD137E00220F8BD206802F0E6F82068816908221143816120688169B94381612068C4\n"
+":402540008169EA6812E0206802F0EEF8206882690121C9020A43826120688169012292029143816120688169EA6812021143816124E0206802F0F1F82068C26908210A43C0\n"
+":40258000C2612068C169B943C1612068C169EA6812E0206802F0FCF82068C1690122D2021143C1612068C269012189028A43C2612068C169EA6812021143C16101207075C1\n"
+":4025C00000203075F8BD70B5040005D025462035687D002802D006E0012070BD00202875204600F00BF802206875211D206802F053F801206875002070BD000010B5006800\n"
+":402600000121890788420CD10648816B012211438163002203210F20FFF74AF80F20FFF73DF810BD001002407047000010B500680249884201D1FEF7BDFF10BD00040040F9\n"
+":402640007047704770470000F8B502680446D06911680607360F07D1830605D58B0603D5204602F05EF9F8BD95682023002E65D0EE07F60FFF2721370F4037435ED0C707E8\n"
+":4026800006D0CF0504D501271762E26E3A43E266820708D5EA0706D0276802223A62E26E04273A43E266420708D5EA0706D0256804222A62E26E02252A43E266020709D5E6\n"
+":4026C0000A461A40324305D0236808221A62E36E1343E366E26E002AC5D0800604D5880602D5204602F01DF9E06E000703D42068806840061CD5204602F004F920688168EB\n"
+":40270000490611D5826840218A438260606E00280AD01D498163606EFEF7EAF90028A2D0606E816B8847F8BD2046FFF78BFFF8BD2046FFF787FF0020E066F8BD2646C70205\n"
+":402740006036002F0ADA6D0208D50120000510627372B3722046FFF774FFF8BD050605D50D0603D5204602F033FAF8BD4006FCD54806FAD52046146840218C431460737295\n"
+":4027800000F0D3F8F8BD0000F148000870B5040005D025466035687A002802D006E0012070BD00202872204600F026F82420687220680168490849000160606A002802D05E\n"
+":4027C000204602F000F8204602F0EAF80128E7D0206841680922D20291434160206881682A229143816020680168012211430160204602F04DF870BD00B50068164987B012\n"
+":40280000884227D11548C26A01210A43C262C26A0A400592C26A0A43C262C26A0A400592826B4B041A4382630C20009002200190032003900420049002910520694600073A\n"
+":40284000FEF768FA002203211C20FEF731FF1C20FEF724FF07B000BD00440040001002407047FFB5064604466036707A83B00D46202858D1002D0CD00598002809D001207C\n"
+":40288000A1680003814207D12069002804D1E80702D0012007B0F0BD307A012843D0012030720020E06621207072FEF705FB019027464037059838820598788218E0788A21\n"
+":4028C000401E788206980090002280212046019B02F0B1F9002818D10120A1680003814202D12069002812D02168287888626D1C788A0028E3D106980090002240212046F9\n"
+":40290000019B02F098F9002808D00320C2E728882168C005C00D8862AD1CE9E72020707200203072B6E70220B4E7704710B5064CE178002901D000F045F8E078401EE070CC\n"
+":4029400001F0D2FC10BD00006000002010B501684A68D243920507D48A68D243D20703D1921E8A60FFF7E2FF10BD10B504000FD000F010F8E0688021084321680860616864\n"
+":4029800020690843A168084321684860002010BD012010BD10B50068084988420CD10848816BC21411438163002203211046FEF77FFE0020FEF772FE10BD0000002C0040A8\n"
+":4029C00000100240C1680068016000207047FEE710B5074800688069172109020842044802D0FEF7DDFA10BDFEF706FB10BD0000AC0D002010B50648006880694005400F9A\n"
+":402A0000034802D0FEF7CCFA10BDFEF7F5FA10BDF80D002010B5806A01684A680123DB031A434A60826B00219163C26B9163014640314A78602A02D0FEF7E6FA10BD20226B\n"
+":402A40004A70FEF789FA10BDF0B503460022CE0740332824B025002E05D05E7842222746B74300D0F2228E0705D544265B7832439C4300D02A434B0701D5B8231A43112385\n"
+":402A80008B4301D190231A4312238B4301D160210A4300680168914301600020F0BD000070B5164D1223446B002220268B43AC4202D0134DAC420DD14C0700D5B82211242B\n"
+":402AC0008C4301D190210A43002B11D1324340210A430DE04C0700D5B822CC0701D0F2242243890701D5F4210A43002B00D132430068016811430160002070BD5D2F000859\n"
+":402B00004931000801688A69D243920701D400228A6200688169C943C90703D081690122114381617047F8B5054604464035687828218143206804D00821C1610020287028\n"
+":402B4000F8BD8169C903CF0F8169FE230E0C81681E408A05C168920D19408C46E168022912D10621D3090E400B409E420BD1A16C491CA164A16C0229E2D10021A1640823BC\n"
+":402B8000C361297007E0664604212046FFF75CFF00202870324639462046FEF7EFF9F8BDF8B50026054640350446AE702C48E0626685606C0843606468782027282823D061\n"
+":402BC0006878292820D068782A281DD007212046FFF73AFF6878602800D06F7026636663206801684A041F49026817D501239B039A430260A06B81632E70A06BFDF778FF6E\n"
+":402C000000281DD0A06B19E003212046FFF71CFF28206870266314486063E1E7120410D502680123DB039A430260E06B81632E70E06BFDF75DFF002802D0E06B816B884742\n"
+":402C4000F8BD6878602804D02E702046FEF7DCF9F8BD6F702E702046FEF77EF9F8BD00000000FFFF152A0008B131000870B504461548E0620025256320222046403006468E\n"
+":402C8000427085706563480711D52068416A606A421C62620170208D002808D0401E2085608D401E6085606C04210843606407212046FFF7C9FE21681020C86135702046C8\n"
+":402CC000FEF75CFA70BD00000000FFFFF8B5064600682027C76130684268224B1A4042600025356320487563F062C80606D531681020C861706C0421084370643046FFF76D\n"
+":402D000001FF03213046FFF79FFE706C002814D134464034607860280FD06078212811D06078222808D16770A078A57040282570304614D0FEF734FAF8BD716C3046FFF7D7\n"
+":402D40002FFFF8BD6770A078A57040282570304602D0FEF737FAF8BDFEF722FBF8BDFEF70DFBF8BD00E800FE0000FFFF70B50025064640360446B570717820202129707021\n"
+":402D80000BD012202063022120466563FFF75CFE35702046FEF704FA70BD11202063012120466563FFF750FE35702046FEF70AFA70BD0000F8B50446006820260F46C6611D\n"
+":402DC00021680820C86107212046FFF73DFE20684168B20211434160206841682D4A114041602046FFF78EFE20680168254649044035002902DB0168090406D5697821293E\n"
+":402E00002FD0E16B096849686185628D0421002A02D0626C0A4362647A070FD5426A606A431C63620270208D002807D0401E2085608D401E6085606C084360640020206380\n"
+":402E4000A8706063616C00290DD0616C2046FFF7A7FE6878282803D139462046FFF706FFF8BDA16BCEE7E26A0B498A4206D0E1626E7028702046FEF781F9F8BD69786E7038\n"
+":402E800022292870204602D0FEF714FBF8BDFEF7E9FAF8BD00E800FE0000FFFF70B50026044640340546A6706178282029290ED061782A290AD160702220286302212846DD\n"
+":402EC000FFF7C2FD26702846FEF7CCFA70BD60702120286301212846FFF7B6FD26702846FEF7E8FA70BD0000F7B5044600680E468069C043C0062CD4202725464035206841\n"
+":402F00008069C04380060FD5701CF8D0002E05D0FDF7D2FF0299401AB042F0D96F700020A87028700320FEBD21681020C8612068C7612046FFF7E6FD20684168064A11403F\n"
+":402F40004160042060646F700020A87028700120FEBD0020FEBD000000E800FEF8B50546044640352878012816D001202870C8060026002812DAD00610D521681020C861B8\n"
+":402F8000606C04210843606412212046FFF788FD2046FFF7B7FD3FE00220F8BD080634D5500632D520680168402291430160608D002825D0206840688105608D890DFF2891\n"
+":402FC00003D9FF202085930403E0608D012320855B060096208DC2B2204600F079F9608D218D401A6085687822282068016804D001229203114301600EE00122D203F9E725\n"
+":4030000040212046FFF7CCFD06E0880604D5900602D52046FFF75AFE2E700020F8BD0000F8B5074604464037387815460E46012810D001203870F0060ED5E8060CD521680C\n"
+":403040001020C861606C0421084360642046FFF759FD5BE00220F8BD700708D5680706D52068416A606A421C6262017009E0B0070ED5A8070CD5606A411C61622168007807\n"
+":403080008862208D401E2085608D401E60853DE02C4A30062FD568062DD5208D002825D1608D002822D0206840688105608D890DFF2806D9FF220020228501231B0600903B\n"
+":4030C00010E0608D2085E06A904205D000200090E36A208DC2B205E000200090208D0123C2B25B06204600F0F3F80FE020684068800123D506E0700608D5680606D5608DBC\n"
+":4031000000280ED040212046FFF74AFDB00605D5A80603D531462046FFF7D8FD00203870F8BD206841688901F0D4E16A914205D141680122920311434160E7E72046FFF757\n"
+":4031400015FEE3E70000FFFF10B5044640342378012B15D001232370CB0618D5D30616D5617821290ED0C16B09684968102200290AD00168CA61416C04221143416414E034\n"
+":40318000022010BD816BEFE70068C2610DE00B0705D5130703D500680821C16105E08B0603D5920601D5FFF705FE0020207010BDF8B5054604464035287816460F460128F2\n"
+":4031C00011D0012028704149F8062DD5F0062BD5628D1020002A08D02168C861606C04210843606467E00220F8BDE36A01225206934202D0E36A934202D16A78282A08D054\n"
+":40320000E26A8A4202D06978292907D02168C86151E039462046FFF729FD4CE02168C8612046FFF76FFC43E0780719D5700717D5608D002820680BD0426A606A431C63620C\n"
+":403240000270208D401E2085608D401E608500E0406A608D00282ED1E06A884228D12AE0380706D5300704D539462046FFF75BFC21E0B8071FD5B0071DD5608D00280CD09D\n"
+":40328000606A411C6162216800788862608D401E6085208D401E20850DE0216862208862E06A01210906884202D0E06A002802D12046FFF7F3FDB80605D5B00603D539462A\n"
+":4032C0002046FFF777FD00202870F8BD0000FFFF70B50568049C68688905890D1204044E11431943304021430143696070BD0000009800FCF8B51C4617460E46054611E0B7\n"
+":40330000601C0FD0002C05D0FDF7D6FD0699401AA04207D92020403568700020A87028700320F8BD286881693046884304D00020B842E5D00020F8BD0120F9E770B51646C5\n"
+":403340000D4604461AE0324629462046FFF7CCFD002801D0012070BD002D04D0FDF7ACFD801BA8420AD9616C202001436164403460700020A0702070032070BD2068806982\n"
+":40338000C0438006DFD4002070BD70B516460D4604461CE0324629462046FFF7A5FD002801D0012070BD681C11D0002D04D0FDF783FD801BA8420AD9616C202001436164E6\n"
+":4033C000403460700020A0702070032070BD20688069C0438007DDD4002070BD8CB000246846848284830483C4480A90C4A001F063FCCB4F002202213846FDF756FD01223D\n"
+":4034000011463846FDF751FD012004F00DF8002201213846FDF749FD012004F005F8012202213846FDF741FD012003F0FDFFC8210120019100900223BA4A0021782003F046\n"
+":4034400045FCB94E050004D0B8A001F035FC357100E03471B34D78220A3D6989BCA001F02BFC2021AE48FDF717FDE870C44D012831D1C821AB4A019100900223921C002178\n"
+":403480000E2003F023FC070004D0BEA001F014FC377100E03471A34F0E220A3FB989C3A001F00AFCB98911229202914201D0CFA044E002F0B9FF070009D0D84AD849D9A0D8\n"
+":4034C00001F0FAFBE34869460883377103E0E2A001F0F2FB347193480A38807801287DD1CF49E9A001F0E8FB8D4F002202213846FDF7DBFC012211463846FDF7D6FC0120A7\n"
+":4035000003F092FF002201213846FDF7CEFC012003F08AFF012202213846FDF7C6FC012003F082FF6846848205A9DD4801F08EFE002806D09B22D200B949DAA001F0BCFB26\n"
+":40354000B9E268466D4F808A393FB84201D1DCA009E0E34AE3A00A9901F0AEFB02F0E0FE002803D0EEA001F0A7FBA4E2F4A001F0A3FB6249684639398182FB480B9102F072\n"
+":403580002BFC05273F07002210213846FDF78DFC80216846017244728172C823032202A9F248FEF7E7FD030002D09F22D20048E2012210213846FDF778FC0022102138464E\n"
+":4035C000FDF773FC8020694608724C728872C823032202A9E548FEF7CDFD00E09AE2030002D08E4A5E322CE21F22C8235201BC49DE48FEF7BFFD030002D0884A653220E2FE\n"
+":40360000012210213846FDF750FCD94B1F225201991AD8A0019301F04FFB022168468182084602F0D9FB012003F0FEFE002210213846FDF73AFC832168460172E02141725A\n"
+":4036400080218172C823032202A9C848FEF792FD030002D0714A8332F3E1E122C8235201C2480199FEF786FD030002D06B4A8C32E7E10520012210210007FDF716FCE12258\n"
+":40368000C94B5201C9A0019901F016FB0A980127400B0890AAE10520002210210007FDF704FC80216846017244728172C823032202A9AE48FEF75EFD030002D0574AA2323D\n"
+":4036C000BFE18748790309180122C8235203A7480991FEF74FFD030002D0504AAB32B0E10520012210210007FDF7DFFB012309985B03C0180090394672E1000038000100D0\n"
+":40370000415031333032205468726561642043726561746564202E2E2E200A0D00000000000400509A000020482C00202041503133303220495350202D204572726F722045\n"
+":40374000434849502049442052656164200A0D004953502043484950204944203D2030782530347820616E6420536C6176652041646472203D20307825303278200A0D003E\n"
+":403780008400002020546F736869626120427269646765202D204572726F7220434849502049442052656164200A0D00546F7368696261204D49504920427269646765202D\n"
+":4037C00043484950204944203D20307825303478202D20536C6176652041646472203D20307825303278200A0D0000000A0D20546F7368696261204272696467652043683B\n"
+":4038000069702049442030782530327820213D20307825303278200A0D000000A9040000D00F02080A0D20257328293A202564204661696C656420746F20496E6974696140\n"
+":403840006C697A65204D49504920427269646765200A0D00F11F00000A204D4950492042726964676520636F6E66696775726174696F6E205375636365737366756C2021B2\n"
+":4038800021200A0D00000000257320456E746572656420546872656164202E2E200A0D0002600000257328256429204572726F7220696E20493243202121200A0D0000009A\n"
+":4038C0000A0D20536B697070696E6720426F6F742044617461202E2E2E200A0D00000000980F01080A20312E20496E697469616C20426F6F7420446174612053697A6520D1\n"
+":403900003D20257520426173652041646472657373203D20307825303878200A0D0000000A0D204572726F7220696E20436F6E6669677572696E6720535049200A0D000098\n"
+":403940000A0D2053504920436F6E66696775726174696F6E20436F6D706C657465202E2E2E200A0D0000000052F00000440E0020781301080A0D20322E205472616E736DFE\n"
+":40398000697474656420307825303878202B20307825303478206279746573203D20307825303878200A0D00982F01080A0D20332E205472616E736D697474656420307885\n"
+":4039C00025303878202B20307825303478206279746573203D20307825303878200A0D00A0A0099A01F068F908987F1CB84200D951E60520002210210007FDF756FA802029\n"
+":403A0000694608724C728872C823032202A9A348FEF7B0FB030001D0A14A12E0A148052101700A997803091A8AB208919E49C82341180F469948FEF79DFB030006D0984A6F\n"
+":403A400009329A499AA001F037F934E00520012210210007FDF729FA089839463B1802469DA001F029F96846848307A9A74801F0EDFB6846818BA64AA6A001F01DF9684646\n"
+":403A800004837D210901012001910090022306AA0621782003F01AF96846018BA7A001F00BF9AD4968468182AC480B9902F094F9012003F0B9FC6846008B9549002801902D\n"
+":403AC00000916846838B06D0754A7849D332A4A001F0F2F80DE0192292017449B0A001F0EBF801F0A3FE00F0A5F97D20C00003F09BFCC821286803F0E3FC6A4881784170B5\n"
+":403B00006946098B00290AD0122282700181286803F0B0FC634FB878092804D01CE0102181700481F3E700220221AB48FDF7BDF901221146A848FDF7B8F9022003F074FC8E\n"
+":403B4000B471C821286803F0BBFCB87878701220B870286803F08EFCB87802280BD1F471C821286803F0ACFCB87878701020B870286803F07FFCB87803280BD13472C8219B\n"
+":403B8000286803F09DFCB87878701020B870286803F070FCB87804280DD101F0ADFE7072C821286803F08CFCB87878701020B870286803F05FFCB87805280DD101F06CFBFD\n"
+":403BC0007074C821286803F07BFCB87878701020B870286803F04EFCB87806281CD101207E4A01900094137A51887820121D03F06DF80090002802D079A001F05DF8009862\n"
+":403C0000F074C821286803F05BFCB87878701020B870286803F02EFCB87807280ED178A001F04AF87475C821286803F049FCB87878701120B870286803F01CFCB8780828B1\n"
+":403C400000D048E475A001F037F8B475C821286803F036FCB87878701020B870286803F009FC38E40A0D20342E202564205472616E736D697474656420307825303878205A\n"
+":403C80002B20307825303478206279746573203D20307825303878200A0D0000440E00206905000090000020980F0108D00F02080A0D25733A25643A205350492054726140\n"
+":403CC0006E736D6974204572726F72202D202564200A0D20000000000A0D20352E205472616E736D697474656420307825303878202B203078253034782062797465732091\n"
+":403D00003D20307825303878200A0D0052F000004DC000000A0D20426F6F74204441544120435243203D20307825303478203C3D3E20307825303478200A0D000A0D204280\n"
+":403D40006F6F7420537461747573203D20307825303478200A0D0000FFFF0000026000000A0D20257328293A2564204572726F7220696E20435243203D203078253034786E\n"
+":403D800020213D203078253034782C2020535441545553203D20307825303478200A0D000A0D20257328293A256420435243203D20307825303478203D3D20307825303423\n"
+":403DC000782C2020535441545553203D20307825303478200A0D00000004005010190020204572726F722052656769737465722052656164204572726F72200A0D00000075\n"
+":403E000020506F776572696E6720446F776E20495350202E2E2E200A0D0000002057616B696E6720557020495350202E2E2E200A0D00000010B508210148FDF732F810BDFD\n"
+":403E400000040050F0B5274887B0C16A01242143C162C16A21400591C26A02210A43C262C06A002508400590202000900195694602951D48FCF74EFF1020052703263F07A2\n"
+":403E8000009001946946039602943846FCF742FF019400966946144803960294FCF73AFF012210213846FDF700F8002202210E48FCF7FBFF012211460B48FCF7F6FFA0021F\n"
+":403EC00000900A480190694602953846FCF722FF002203210720FDF7EBFB0720FDF7DEFB07B0F0BD00100240000400500000111010B51248104901601149416084218160B7\n"
+":403F00000121C1600021016141618161C1610162FDF7DAF800280BD100210848FCF7D2FF002805D100210548FCF7F1FF002801D0FCF7EAFC10BD000000540040AC0D002058\n"
+":403F40002A12B00010B511480F49016010494160002181600161416181610122C161C2600162FDF7B1F800280BD100210748FCF7A9FF002805D100210448FCF7C8FF0028D9\n"
+":403F800001D0FCF7C1FC10BD00780040F80D0020330F600010B50F480D490160FF21053141600021816002220261C16001224261C161016252024162826181620721C1626D\n"
+":403FC000FEF76EF8002801D0FCF79EFC10BD000000300140440E002010B5164A164886B0910706C02021016000241E21846041600838FEF7E8FA002814D1049404A90E48D0\n"
+":404000000594FEF783F900280CD1602000900420019003900022694602940748FEF76BFA002801D0FCF770FC0348FEF74DFA06B010BD000055D000009C0E002010B50C489F\n"
+":404040000A490160E1214902416000218160C16001618161C1610C22016242614162FEF795FB002801D0FCF74FFC10BD00440040D40E002010B50CA000F01EFE0F480E4904\n"
+":404080000160FF21813141607F218160C160012149020161FEF769FC002801D0FCF734FC07A000F009FE10BD20494E49542057574447200A0D000000002C0040440F002017\n"
+":4040C00020494E495420575744472053554343455353200A0D000000704700008307FF22DB0E9A408907090E994000280BDA0007000F0838830808489B001818C3699343F3\n"
+":404100000B43C3617047830804489B001B181868904308431860704700ED00E000E400E0BFF34F8F04490348C860BFF34F8F00BFFDE700000400FA0500ED00E038B50D46C0\n"
+":404140001A494418206800902346194A19491AA000F0B2FDE8430004284320602068144A00902346521D134922A000F0A5FD2E4CA069C007FCD10E4A0E490D322BA000F009\n"
+":404180009BFDA069800702D50220A06105E0084A084914322AA000F08FFD4F22120105492EA000F089FD002038BD00000000F81FD9040000548C0008202D2D2D2020426534\n"
+":4041C000666F7265202573282564292041742041646472657373203078253038782056616C7565203D20307825303878202D2D2D200A0D00202D2D2D20257328256429207B\n"
+":4042000041742041646472657373203078253038782056616C7565203D20307825303878202D2D2D200A0D0000200240202D2D2D20257328256429202D2D2D200A0D000078\n"
+":40424000202D2D2D204552524F52202D20257328256429202D2D2D200A0D0000202D2D2D205355434345535320257328256429202D2D2D200A0D000070B517490023CA6806\n"
+":404280001206120F18D18A6B154CD500134A02D51268224009E08E6B01252D072E438E6312688E6B2240AE438E63A24204D103218903884200D101230A48016849084900CF\n"
+":4042C000194301600068C007C00F984201D0012070BD002070BD00000010024000700040001800000020024070B512A000F0E4FC154D286801684908490001602868002490\n"
+":404300008462286844624B2149011048FCF79FF90F4805210482818141818471FF210171417129680A6801231A430A6081784170847070BD524553455420534C41564520D1\n"
+":40434000493243200A0D0000AC0D0020580F00206000002010B50248FDF741FE10BD0000440E0020F8B51D4616460F460446FCF7A3FD314626464036009000291ED043E026\n"
+":40438000681C1BD0002D05D0FCF796FD0099401AA84213D920684168E022914341602068026840218A43026023E021680A6882430A6021680A6802430A601FE020688168CC\n"
+":4043C00038468843DCD124E0681C1DD0002D06D0FCF772FD01460098081AA84214D920684268E0218A434260206801684022914301600120A16A40038142D6D0012070740E\n"
+":40440000002030740320F8BD2068816838468843DAD00020F8BD704730A000F04DFC0025344C0426A078042801D1FFF75DFFA289002A04D0A078082805D00C2803D0A0784B\n"
+":40444000002802D010E06070A5706281A58165700A20A07028492948FDF754F8002803D027A000F029FC2EE0A0780C2804D008282DD1A08900282AD11E4B61890C331A1DEB\n"
+":404480001D4802F0D3F8002808D06922D200284928A000F011FC3348208111E0228A002A15D0E2812582A07860700620A07012491248FDF753F8002809D02BA000F0FCFBB0\n"
+":4044C00060780428AED0A0786070A670AAE70520E07009481438FEF775FAA3E720456E746572656420736C617665207468726561640A0D0060000020580F0020AC0D0020FA\n"
+":404500004572726F72204F6363757272656420696E2048414C5F4932435F536C6176655F526563656976655F4954200A0D000000508B000820257328256429204572726F35\n"
+":4045400072206F636375726564206F6E20686F73745F6672616D65776F726B202121200A0D00000008200000204572726F72204F63637572726564206174205472616E735D\n"
+":404580006D6974200A0D000010B502F0CDFF10BD10B523489AB001680322D2029143C21489180160012102200391102100900491099040040B90000100240C900A946846EF\n"
+":4045C000FDF716FB002817D10F20159003201690179418940121199415A8FDF7D3F900280AD1FF200B3012940D90109413940DA8FDF70CF9002801D0FCF786F9FDF796FADE\n"
+":404600007D21C900FBF7B0FFFDF768FE0420FDF759FE03210022081FFDF74AF81AB010BD0070004010480168821511430160C1680E4A1140C16001680D4A11400160816864\n"
+":4046400049084900816001680122920491430160C168FD2212049143C160002101610549C003886070470000001002400C40FF88F6FFF6FE00ED00E010B50248FDF791FE75\n"
+":4046800010BD00009C0E002010B50248FDF789FE10BD0000D8180020F0B502680124A407124D134E134FA04205D0A84203D0B04201D0B84204D11346702293434A681A4325\n"
+":4046C000A04205D0A84203D0B04201D0B84204D103231B029A43CB681A4302608A68C2620968816201214161F0BD000000040040000801400014014030B5026A52085200E8\n"
+":404700000262026A456883697024A3439C080B68A40023430224A2438C6845601443836149684163046230BD30B5026A10239A430262036A4568826973242402A2430C680E\n"
+":4047400024021443202293438A68456012011A43846149688163026230BD30B5026AFF2301339A430262026A4568C3697024A3439C080B68A400234301246402A2438C68A6\n"
+":40478000456024021443C3614968C163046230BD30B5026A01231B039A430262036A4568C26973242402A2430C68240214430122520393438A68456012031A43C4614968B2\n"
+":4047C0000164026230BD10B5818CC90707D001684A6801235B049A43836A1A434A60818C890707D501684A6801231B049A43C36A1A434A60818C490707D501684A680123BB\n"
+":404800009B049A43036B1A434A60818C090707D501684A680123DB039A43436B1A434A60818CC90607D50268916801231B039943836B19439160818C890607D501688A6898\n"
+":4048400001235B039A43C36B1A438A60818C490612D503685A6801210905046C8A4322435A60026C8A4207D10268516803235B059943436C19435160818C090607D50168B4\n"
+":404880004A680123DB04806C9A4302434A6010BDF8B500260446C666FCF70EFB054620680068124F000709D501212B46002249052046009700F0BFF900280DD1206800685A\n"
+":4048C00040070BD501212B46002289052046009700F0B1F9002801D00320F8BD202060346072A07226720020F8BD0000FFFFFF0110B5806A0022014640314A834A82FDF7AD\n"
+":40490000A1FE10BD01680A68FF2321339A430A6001688A68520852008A60202160308172704770B50246403201466031938B8D7A0C460168222D05D08869082210438861F5\n"
+":40494000022070BD496A01268568360389B2B54202D10569002D0BD01940436D5D1C45651970518B491E0904090C518307D015E0456D19402980416D891C4165F1E70168C5\n"
+":404980000A68FF2321339A430A6001688A68520852008A602021A172FDF762FF002070BDFEB50446016880682269E36910436269102700261A4310430A683546784B1A4087\n"
+":4049C00002430A6020684168032212039143E26811434160734A2168A069914201D0226A10438A680B231B029A4302438A606E4A20686E4990420CD1C8688007800F06D0AD\n"
+":404A0000012843D002283FD0032826D124E0012723E0674A90420AD1C8680C21084031D0042833D008282FD00C2816D114E0614A904227D0604A904224D05A4A90420CD108\n"
+":404A4000C9680320800201401CD01015091A1DD0091A19D0814200D108270220FCF72CFE0190504B514922684039D81300929A4235D1002F0CD0022F0DD0042F12D0082F63\n"
+":404A80001CD113E00027E8E70227E6E70427E4E7FDF752F808E00868C00601D5474805E0474803E0FDF768F8002873D0626851005118814202D81103814201D2012569E023\n"
+":404AC000010E06025008002330185941FBF776FD032109023B4A411A914259D9EEE7E26982422DD13B0000F0F7F80906080B24192424241F2400019812E0FDF72DF80FE02C\n"
+":404B000008686168C00602D548082F4A01E02F4A48088018FBF728FD86B20BE0FDF72CF8616840004A08F4E76168012248081204EFE70125310909013007400F084327E0A2\n"
+":404B40003B0000F0C9F809070A0D061D060606290600B3E7FCF7F0FF14E0FCF7FDFF11E008686168C00602D54A08144801E014484A081018FBF7F8FC81B20098C16009E078\n"
+":404B8000FCF7FAFF61684A088018FBF7EDFC80B22168C8602846FEBD61684A08E9E70000F369FFEF00480040003801404010024000440040004C00400050004000093D00C1\n"
+":404BC0000024F400FFFC0F0000127A000048E8016921095C212901D00220704702464032518A002912D0012381681B03994202D10169002915D0C16C4B1CC364006809785E\n"
+":404C00008162508A401E50820020704701680A6880239A430A6000680168402211430160F2E7C16C03680988C905C90D9962C16C891CC164E5E7FFB581B017460E460446BF\n"
+":404C40000A9D1DE0681C1BD0002D05D0FCF734F90499401AA84213D920680168FF22A1329143016020688168490849008160202060346072A07200202072032005B0F0BD3D\n"
+":404C80002068C1693046884304D00020B842D9D00020F3E70120F9E710B50248FDF7D4FC10BD0000D40E002010B50248FDF74EFE10BD0000440F00200FB410B503A9044BBB\n"
+":404CC000044A029800F024F810BC08BC04B0184711660008A000002030B47446641E2578641CAB4200D21D46635D5B00E31830BC184702E008C8121F08C1002AFAD17047C6\n"
+":404D00007047002001E001C1121F002AFBD17047FFB591B00F460546002606E025280AD0149A139990476D1C761C28780028F5D1304615B0F0BD002400940121F34A0294E4\n"
+":404D400000E004436D1C2B780846203B98401042F7D128782A280ED0022128780246303A092A15D8009A0A235A43303A80180C436D1C0090F1E701CF0090002805DA0120B2\n"
+":404D800040030443009840420090022004436D1C28782E2815D10420044368786D1C2A280AD101CF6D1C02900BE002990A225143303940186D1C0290287801463039092961\n"
+":404DC000F3D928786C2810D006DC4C281AD068280ED06A2817D104E0742813D07A2812D110E00120400504430CE00121090501E0032109050C436978814203D1012000050A\n"
+":404E000024186D1C6D1C287803906E281ED00CDC632831D004DC00288AD0582811D1B2E064287BD069280CD178E073282DD004DC6F2870D0702804D1A7E075286CD078284A\n"
+":404E40006BD0149A13999047761C62E06002400F022807D003280AD0042838680AD006603F1D56E03868F11706604160F8E738680680F5E70670F3E73878694608740020C2\n"
+":404E8000487404A80390012003E0386803900020C0433F1D61070FD5002101E00199491C029A0191914213DA8142F7DB019A0399895C0029F2D10BE0002101E00199491C7D\n"
+":404EC00001918142FADB019A0399895C0029F5D101990098139A401A00902146149B00F03BF901998019461807E0039803990078491C0391149A139990470198401E0190A1\n"
+":404F0000401CF2D12146149B139A009800F014F986196D1C09E741E033E034E00A200021049005916002410F022905D001CFC2179446032905D007E0FF1DFF08FF0003CF14\n"
+":404F400006E000B2C2179446042902D140B2C1178C4600226146944506DA0A460021404291418C462D2102E0210504D52B216A461176012103E0E10701D02021F7E7019110\n"
+":404F800054E00A200BE0102009E01020049000210420044308200591029003E008200021059104906002410F022905D001CF00229446032906D006E0FF1DFF08FF0003CF3F\n"
+":404FC0008C4603E080B2042900D1C0B20021019121072BD50399702906D0049A1021059B4A401A4305D00EE040216A461176012108E06146014306D030216A4611760399D4\n"
+":40500000517602210191049A0821059B4A401A430CD16146014301D1610707D530216A461176012101910299491E02910399582904D037A103910FA90F910DE039A1F9E79B\n"
+":405040006146059B049AFBF7B9FA039B8C469B5C0F9A521E0F92137061460143F0D10F9807A9081A20300390600704D5012000048443029801E0012002900399884201DD5C\n"
+":40508000401A00E0002041180290019809180098401A0090E00306D42146149B139A009800F05AF886190020049008E006A9085C149A139990470498401C761C04900199DE\n"
+":4050C0008842F3DBE0030CD52146149B139A009800F042F8861904E0149A302013999047761C0299481E02900029F5DC08E00F980F990078491C0F91149A13999047761C35\n"
+":405100000399481E03900029F1DCFBE60928010030313233343536373839616263646566000000003031323334353637383941424344454600000000F8B5044600251E464D\n"
+":405140001746880404D405E039462020B0476D1C641EF9D52846F8BDFFB50446002581B01E46C80301D5302700E02027880404D505E038460399B0476D1C641EF9D528465E\n"
+":4051800005B0F0BD70B50D46002812D001780446432903D015A0FFF78FFD0AE00221A01C01F0A8F821790246914204D017A0FFF783FD022070BD22480178052901D0214A26\n"
+":4051C00011706178017061880802090A084381B2012901D9012100E000214018801C2880194901200870002070BD000020496E76616C6964205369676E617475726520304C\n"
+":405200007825303278202121200A0D0020476976656E2020435243203D2030782530327820213D2043616C63756C6174656420435243203D20307825303278200A0D000026\n"
+":405240006500002064000020660000207CB50546C8220120019200900A4602232946782001F034FD041E04D0294602A0FFF724FD20467CBD204572726F722052656164696B\n"
+":405280006E67207265676973746572202578202121200A0D00000000FEB5F64F0021F88C6A4691800D22920103465343F34CF24EF24A1C19D2583346316825791B7991420E\n"
+":4052C00001D1AB4204D0EEA00095FFF7F5FC3CE2012B0BD1B168E268914202DCA368994206DAF7A0A368FFF7E7FC2EE20920FEBDE0497822088550434518A818DE49FBF789\n"
+":405300008DF9F54AA86FDB4F811A203790425BD019DCF24A811A90426ED009DCF049401833D001283CD0022844D00C2828D1B4E0032956D00226EB4C042975D0052974D05A\n"
+":405340000A291DD1BAE0CB4CE74A2646881A6036403491426CD00BDCE448081867D0012873D0E1210901072870D0082808D12AE217286CD019286BD01B286AD01D2869D0AB\n"
+":40538000DB49DCA0FFF798FCB0E7803528780006010C0720000300F01FFD2878F8723FE2803528784006410CD84800F015FD2878387335E2803528780006010CD44800F083\n"
+":4053C0000BFD287878732BE2803528780006010C68468180CE480A3000F0FEFC2878B8731EE280352878010268468180C94800F0F3FC2878F87313E280359E4C6421286846\n"
+":40540000FBF7C8F80007060C08036421FBF7C2F80105090D314368468180BD48001D00F0DBFC28882086FBE172E053E000E0A1E0904E8035288870863978B74800290AD039\n"
+":4054400001291BD0022919D014E07EE088E175E178E1D8E1DEE1FF2229689632914201DB002105E0C839CD2901D2012100E0032100F0B2FC3878032804D008E0296896297D\n"
+":40548000F3DBEDE72079012805D0022803D02888708680B281E16420FAE780352868002809D09E49684681805120000200F094FC28783875B4E199490839F3E78035288804\n"
+":4054C0006C4C81B268468180954800F085FC2888E086A5E101A92046FFF7B8FE80352868002805D03978002902D0012804D00CE068468188314304E068468088C107C90F30\n"
+":4055000068468180204600F067FC2878B87687E101A92046FFF79AFE80352868002802D001280AD103E069468888304004E0694688880121084369468880684681882046F6\n"
+":4055400000F04AFC2878F8766AE10421754800F043FC80352E68642046436E483146801D00F06AFC6C483146143000F065FC2888608555E180352868002801D002284CD103\n"
+":405580000621684800F028FC62482C21001F00F023FC5E4840210A3000F01EFC5D480021303000F019FC5B480021323000F014FC584801218903343000F00EFC55480121D4\n"
+":4055C0008903363000F008FC29682A48022903D1317B006F00F000FD3878534F53497A100300FFF779FB060406060C0E101A4A4979314948103000F01FFC394609E01146A4\n"
+":40560000F7E7114600E04A494348103000F014FC48494148143000F00FFC2868012825D10421404800F0D8FB3A482021001F00F0D3FB364800210A3000F0CEFB3E4F364842\n"
+":405640003946103000F0F8FB3946334F1437384600F0F2FB648D642044432E482146801D00F0EAFB2146384600F0E6FB28783072D6E00000101900205C2D0020988D0008C9\n"
+":405680000A0D204374726C2049442030782530387820213D20307825303878206F72204374726C20547970652030782530327820213D20307825303278200A0D000000009E\n"
+":4056C0000A0A0D202564203E20256420203C202564200A0A0D0000001B0998001009980000F767FF0C100000F2FF01001A00FEFFDE0F020825733A20756E6B6E6F776E206B\n"
+":405700006374726C2069642E0A0D0000DA5200000670000006500000142000005F1100000A510000405400006A0401006533000050C30000400D030040420F0080352878A7\n"
+":4057400030736DE0307A022801D00220FEBD3548803529680167317B286800F03DFC5FE0304E8035286830642868FAF713FF05461621615E01208003401AFF216931FAF714\n"
+":4057800009FF6083012168434903081AA08131E0022832D1642070862FE000F033FDE189214800F019FB2048618A801C00F014FB1D48218A001D00F00FFB1B48A18A801DA4\n"
+":4057C00000F00AFB2CE0174E80352868B0642868FAF7E0FE05461821615E01208003401AFF216931FAF7D6FE60830121684349034018A0833878032801D0708ECDE720795D\n"
+":405800000128C7D0C4E78035286800F03BFC2878787705E08035286800F040FB287820710020FEBD101900200420000010B581211D4800F0D1FA1D48817A1D48002904D0EB\n"
+":40584000142100F0C9FA1BA003E0122100F0C4FA1EA0FFF731FA16480021203800F0BCFA2049214800F0B8FA0021204800F0B4FA2C211F4800F0B0FA1D481E490A3000F086\n"
+":40588000ABFA1B4803218902443000F0A5FA01214903481000F0A0FA002000F0F3FB00F027FF002010BD0000861100003019002030200000436F6E6669677572696E6720F2\n"
+":4058C00034206C616E650A0D00000000436F6E6669677572696E672032206C616E650A0D00000000FFFF00000A1000000C7000000250000014820000F0B585B000250195E8\n"
+":405900000095F34AF14C9068A67A844620462038478C182047431368D1681069049352680392002E30D0EB4A2646203ED259768C18277E43E74F31E0F3889C4536D0B088D5\n"
+":40594000F38861466C460BC4E348039B0499FFF7B3F916E07289914202D1B18988422BD0DEA00CE0F289914224D87289914221D3318A884202D8B18988421DD2DFA0FFF7A9\n"
+":405980009BF9022005B0F0BDD24AD04E9032203ED259768C18277E43CE4F9037F6199342CDD1B788039BBB42C9D1C5E7327A012AD8D1CFE7DAA0E2E7C4481422C4491438AE\n"
+":4059C000FAF72CFEC14EDF48203EF168C14219D13021DD4800F000FA308A81B20120400300F0FAF9B08A81B2D748103800F0F4F92078D64F00280AD0A07E002807D0012868\n"
+":405A00000BD012E0D2A0FFF757F90920BAE73846009900F0E1F9022104E03846009900F0DBF90099384600F0D7F9C74805213269C9010E308A420AD17825290200F0CCF981\n"
+":405A4000C1480221801C00F0C7F9002047E005231B0219019A4209D1502500F0BDF9BA480121801C00F0B8F9012038E00F23DB019A4209D1502500F0AFF9B3480121801C13\n"
+":405A800000F0AAF902202AE00F231B0259009A4209D11E2500F0A0F9AB480199801C00F09BF903201BE001231B039A4209D11E2500F092F9A4480199801C00F08DF90420C0\n"
+":405AC0000DE0832149018A420AD11325290200F083F99D480199801C00F07EF9052020702B46A6A072693169FFF7E6F8708E00F089FB764D94482035E9890E3800F06CF9AB\n"
+":405B00009148698A0C3800F067F98F48298A0A3800F062F98C48A98A083800F05DF9718EA3A0FFF7C9F82078002804D0012825D0022823D010E0708EFF219631884201D326\n"
+":405B4000002105E0C838CD2801D2012100E002217D48801C00F040F99A485C4F4079403700282FD0207805283FD004283DD0954900204871387A012804D023E0708E962892\n"
+":405B8000E3D3DDE78121904800F026F9698DFF204E30814208D88B4A1279012A04D0A02907D8022A05D00DE0012129716885874905E002202871A0207D216885C9018448BD\n"
+":405BC00000F03AF9207803280FD17E48007902280BD101202871FF204E3068857B497C4800F02AF9774901200871708E00902078032806D12879012801D0022801D164201E\n"
+":405C00007086708E00F0FEFA4F48E9890E3800F0E3F84D48698A0C3800F0DEF84A48298A0A3800F0D9F84848A98A083800F0D4F8009870862178002908D0012917D0022971\n"
+":405C400015D0052916D0042914D01FE0FF219631884201D3002105E0C838CD2801D2012100E003213848801C00F0B6F80EE09628F5D3EFE78021544800F0AEF82879002802\n"
+":405C800004D050490120487100202871387A01280AD1504D2C482946123000F0CDF82A482946163000F0C8F8607F002801D000F0E9F9254807210902103000F08DF80121BF\n"
+":405CC0004903481000F088F800205BE630190020482D0020788C00081C110208496E76616C6964204672616D652052617465202D2044495343200A0D00000000496E76611B\n"
+":405D00006C6964204672616D652052617465202D20434F4E54206D696E200A0D00000000496E76616C6964204672616D652052617465202D20434F4E54206D6178200A0D7B\n"
+":405D400000000000ABA6A9A6122000000C1000005468697320666F726D617420307825303878206973206E6F7420737570706F72746564202F6E2F7200000000204368612A\n"
+":405D80006E676564204672616D652053697A6520746F2025642078202564204672616D652052617465203D202564200A0D000000205A6F6F6D204C6576656C203D202564BB\n"
+":405DC000200A0D009000002086110000148200000C50000040420F003EB5044668460181C821002001910090022302AA2146782000F06CFF030005D068460289214602A0C5\n"
+":405E0000FEF75AFF00203EBD4572726F722057726974696E6720726567202578203D203078253034782020657272203D20307825303278200A0D00003EB505460291C8210C\n"
+":405E4000002001910090042302AA2946782000F03DFF040007D00346294604A0029AFEF72BFF20463EBD00203EBD00004572726F722057726974696E672072656720257843\n"
+":405E8000203D203078253034782020657272203D20307825303278200A0D0000F8B5424C06462746254620376035002804D0022E41D0012E3FD075E03C493D48FFF7BCFF02\n"
+":405EC0003C4EB079002801D002286BD13A783A483A493B4F1300FEF7FFFE060406060A18181035496931FFF7A7FF364901E03649F9E73148001DFFF79FFF2C213348FFF78F\n"
+":405F00006BFFB079022805D00AE03946FFF794FF2F49EEE702202872297B206F00F05CF8B079002804D128724021204800F054F80120B07136E03878052833D0042831D033\n"
+":405F40001C48297A817120212048FFF745FF002028721D491D4A144DFF204E3021390A324035012E02D0022E02D00BE0688506E03B78032BFAD0A0207D216885C9011046DE\n"
+":405F8000FFF75AFF81210A48FFF726FF3878032806D1FF2101310F48FFF71EFF642060862E71F8BD0220F8BD10190020808000008611000090000020242000006533000014\n"
+":405FC00050C300006A0401003582000002500000400D030010100000F8B50C462649884249D80104254F0E0EC5B269463846FFF72DF9694608887911084381B23846FFF73D\n"
+":40600000EBFEB6086408301B00B269460880002800DA002008800006010C1948FFF7DCFEAD08281B00B269460880002800DA002008800006010C1248801CFFF7CDFE30198D\n"
+":4060400000B269460880402800DD402008800006010C0B48001DFFF7BFFE281900B269460880402800DD402008800006010C0448801DFFF7B1FEF8BDFFFF000010200000F9\n"
+":4060800036500000F8B500216A46FF2611800224584F594D73360300FEF71EFE06043A50667D943411463846FFF7D0F868460188A14301803846FFF78FFE00212846FFF702\n"
+":4060C0008BFE4E484D4900782039002804D001281AD0022818D004E0488EFF219631884201D3002105E0C838CD2801D2012100E003214348FFF770FEFF2171313E48001F70\n"
+":40610000FFF76AFE0020F8BD488E9628EED3E8E711463846FFF79AF868460188214301803846FFF759FE00212846FFF755FE04213348FFF751FEFF218031DFE7114638469B\n"
+":40614000FFF784F868460188214301803846FFF743FE04212A48FFF73FFE27483146001FFFF73AFE002143E011463846FFF76EF868460188214301803846FFF72DFE04218A\n"
+":406180001F48FFF729FE1C483146001FFFF724FE012109032CE011463846FFF757F868460188214301803846FFF716FE04211448FFF712FE10483146001FFFF70DFE0121B9\n"
+":4061C000490315E011463846FFF740F868460188214301803846FFF7FFFD04210848FFF7FBFD05483146001FFFF7F6FD03210903284685E70A100000CE52000030190020F3\n"
+":4062000014200000F8B50746374802787D20C000002A0BD0354B012A0AD0022A08D0032A06D0042A07D0052A09D00AE0304907E001461C4605E02D4C0146583401E00146F0\n"
+":4062400004467D204004FAF7A5F9642148433946FAF7A0F906B2244D7D202035EE8221464004FAF797F9642148433946FAF792F904B228462C834038E121006C0901FAF7D5\n"
+":4062800089F9074601208003FF21801B6931FAF781F901217843490347182846AF814038E121806C0901FAF775F9009001208003FF21001B6931FAF76DF968830099484347\n"
+":4062C00001214903081AF10F891949107A1AA883EA81E20F12195210831A79186B8229828018A8820020F8BD3019002026050000F30300000346002010B50246002B05D00E\n"
+":40630000002903D04B246401A14205D9002010BD9C5C6040521C92B28A42F9D310BD0000FEB5002405273B487D2636013A4D02900EE0042302AA394978200196009400F0C1\n"
+":40634000C5FC002802D0072802D04FE02C7104E038467F1EFFB20028EBD1002F56D03048042702900721042302AA490378200196009400F0ABFC002802D0072836D101E0C5\n"
+":406380002C7104E038467F1EFFB20028EAD1002F3CD0012001F048F81E48083004270290042302AA1D4978200196009400F08EFC002802D0072819D101E02C7104E038465C\n"
+":4063C0007F1EFFB20028EBD1002F1FD01548042702900721042302AA490378200196009400F074FC002803D0072803D02871FEBD2C7104E038467F1EFFB20028E9D1002F1A\n"
+":4064000004D0012001F010F80020FEBD05202871FEBD000020002B00482C002038F000000130330311929119FEB50120694608810024C826022302AA19460E2001960094B8\n"
+":4064400000F044FC4B4D070078D10A2000F0ECFF68460481022302AA19460E200196009400F034FC070069D1012000900223424A002101960E2000F029FC07005ED13E48C9\n"
+":4064800011220C3881899202914205D03BA0FEF713FC02202871FEBD444869460881022302AA04210E200196009400F00FFC070044D1612069460881022302AA08210E20BF\n"
+":4064C0000196009400F002FC070037D138A0FEF7F3FB424869460881022302AA16210E200196009400F0F2FB070027D13C4869460881022302AA18210E200196009400F0AB\n"
+":40650000E5FB07001AD1052069460881022302AA20210E200196009400F0D8FB07000DD10520400269460881022302AA22210E200196009400F0CAFB070005D029A0FEF7BE\n"
+":40654000BBFB2F713846FEBD304869460881022302AA60210E200196009400F0B7FB040005D020A0FEF7A8FB2C712046FEBD0020FEBD0000482C00209C0000200A0D2054EA\n"
+":406580006F73686962612042726964676520436869702049442030782530327820213D20307825303278200A0D00000049020000204D4950492042726964676520434F6E3D\n"
+":4065C0006669677572656420666F72203936204D687A202121200A0D00000000364000001306000020546F736869626120427269646765202D204572726F72204348495036\n"
+":406600002049442052656164200A0D000285000013B5044B012269460348FCF722F900981CBD0000FFFF0000D40E0020F8B51D461446002825D0002923D0002C21D04B266F\n"
+":406640007601052903D1114A1278002A09D0224600F08EFF07000ED00DA0FEF72DFB3846F8BD1946FEF78EFD070001D012A0F4E70020208002E02088B04202D82888B042F6\n"
+":4066800001D90220F8BD0020F8BD0000660000204572726F72206F6363757272656420696E2070726F636573735F636F6D6D616E64200A0D000000004572726F72206F63C6\n"
+":4066C00063757272656420696E20616E616C797A655F6C656E6774685F7061636B6574200A0D0000EFF30580002800D001207047F0B533490023CB720420087312204873D7\n"
+":40670000102088730620C87308462038DC2202866422428601250D752A4AC2868B760446CB766034FF26024623724E364032568508262673244C036404676E038364968184\n"
+":40674000D381AC03148253829482D4821483538396834B7715711D4AC2600522D2010261FF22E13242611A4D0B7000220D239B0116465E4378235343AF591C18A767234603\n"
+":406780007619377960342777012F15D0347A80331C71F4689C60521C282AE7D38A7A0B4AC2600522D201782102618A0042610122C26181610020F0BD803334691C60EAE763\n"
+":4067C00030190020881300008080000055595659988D0008002808D00C490D4A8978002905D00320D0750020704702207047417803780802184341BA06480023022903D045\n"
+":4068000001218172D375EEE78372FBE790000020482C00203019002070B5104CA078102808D00F49112814D0122814D001208871002070BD0B4D0121286800F041FE00289E\n"
+":4068400001D0012070BD0920A070286800F012FEEEE70320EBE70820E9E7000090000020482C002084000020FEB500220446684602811646002907D003200880002C41D0F2\n"
+":406880002578FF2D02D004E00220FEBD1E48057825701E498878FF280CD00F23002822D0122820D0F027112820D0C00621D46770A27022E016486946088101200090019066\n"
+":4068C000022302AA0621782000F000FA060003D010A0FEF7F1F915E068460089000A60706846008908E06370F12005E06370A77003E00889010A6170A0700E48405D002863\n"
+":4069000000D006463046FEBD6400002090000020F10F0000204572726F722052656769737465722052656164204572726F72200A0D000000482C002030B500290AD0244B5F\n"
+":406940009B78102B0CD02348D90605D401210174084630BD022030BD03210174084630BD0024282802D30C800A2030BD78235843194BC018034660331D7F012D02D0022D10\n"
+":4069800015D001E009240C80002A1FD0816F090E1170816F090C5170816F090A9170816FD170197F1171197F012903D00EE00C80092030BD80300168090E51710168090C0D\n"
+":4069C00091710188090AD17100781072002030BD90000020482C00201019002070B50024002905D0282805D3002008800A2070BD022070BD0D239B01344D584343191E798B\n"
+":406A0000012E02D0022E05D101E0152601E09E890A360E80002A56D02958090E11702958090C5170295A090A9170285CD070187910711879012802D0022844D12CE0986859\n"
+":406A4000000E50719868000C90711889000AD071187A1072D868000E5072D868000C90729889000AD072187B10731869000E50731869000C9073188A000AD073187C107470\n"
+":406A80005869000E50745869000C9074988A000AD074187D107516E0187A5071D868000E9071D868000CD0719889000A1072187B507205E0181920301119007C8872641C3B\n"
+":406AC000D868A042F6D8002070BD0000988D0008F8B500271646002905D0282805D3002008800A20F8BD0220F8BD0D22920150431E4A851828792C46A034012802D0022812\n"
+":406B000009D11CE0207E032801D0232002E0A07E400124300880002E25D02946983120223046F9F77BFD3046217E2030017000214170617E8170217E032905D013E0A889CE\n"
+":406B40000A3008800920F8BDA17EC17008E078012918801920222430BB31F9F75FFD7F1CA07EB842F3DC0020F8BD0000988D00087CB50024054600291ED002200880002D0A\n"
+":406B800018D0C82101200191009002230B4A0021782000F09BF8040004D009A0FEF78CF80D484470054E0DA00A3E7189FEF784F87089288020467CBD02207CBD9A00002000\n"
+":406BC0004572726F72204348495020494420526561640A0D00000000482C002043484950204944203D20307825303478200A0D0030B500290AD0334B18249D7A00234443C2\n"
+":406C0000002D28D0062828D22F482BE0022030BD0D2500E015250D80002A51D00159090E11700159090C5170015B090A9170005DD0709888000A107118795071D888000ABC\n"
+":406C400090719879D071187A1072187A01280ED0022835D116E0062802D30B800A2030BD1948903023181D7A012DD3D1D0E75889000A5072987A90729889000AD072187B0C\n"
+":406C800010731DE05889000A5072987A90729889000AD072187B1073D889000A5073987B9073188A000AD073187C1074588A000A5074987C9074988A000AD074187D107573\n"
+":406CC000002030BD30190020788C0008FFB585B01D460E980F9B14460E4601280DD8042D0BD8002C09D0604A00215164320AF1B2002872D0012860D102E0022009B0F0BD14\n"
+":406D00006846027141710093022301AA56480599FAF7A8FA07001FD05348FAF7D3F90446059800903346224639465048FDF7C4FF4D4D28680168490849000160012000F03B\n"
+":406D400073FB286801680122114301601EE0042C7ED0032F7CD081E000200190029003904348092101702B4601AA3F480599FAF73BFA07000DD03C48FAF7A4F90446009640\n"
+":406D8000024639463B48059BFDF796FF202C67D0DDE700F0E8FB364E02E0012000F044FB30780928F9D0012D04D0022D06D0042D58D108E068460079207053E06846808805\n"
+":406DC00040BA20804EE00198694600BA000AC97900020843206045E0FFE720686C4622716171012D04D0022D04D0042D0DD105E0A0710AE0020AA271E07106E0020EA27199\n"
+":406E0000020CE271020A227260720093AB1C01AA15480599FAF726FA040023D01248FAF751F905460598009033462A4621461248FDF742FF0C4E3068016849084900016035\n"
+":406E4000012000F0F1FA306801680122114300E006E00160202D03D0032C01D005204DE707204BE7002049E7F80D0020701102089000002018120208C4110208F8B5114DD7\n"
+":406E8000114CA878002807D0122805D0112817D0082020710820F8BD0C4E0121306800F00FFB0127002805D009A0FDF705FF27710120F8BDAF70306800F0DCFA0020F8BDFD\n"
+":406EC0000320E6E790000020482C0020840000200A0A0A0D2053656D2057616974204661696C6564202121200A0D000070B5104C1049A078112808D00725102809D012281D\n"
+":406F000007D0002805D04D750AE001204875082070BD094E0121306800F0D2FA002801D0072070BDA570306800F0A4FA002070BD90000020482C002084000020FEB5054616\n"
+":406F40000F46002069461C460881002A0BD01F4901268B780321102B0AD01D48DA0604D486740120FEBD0220FEBD81740320FEBD012F05D0022F05D0042F05D01080F2E713\n"
+":406F8000118003E0042000E006201080002C1AD011882046F9F75BFB280A2070657000963B4602AA294678200196FFF78FFE050004D008A0FDF780FE2846FEBD684600897A\n"
+":406FC000010AA170E0700020FEBD000090000020482C0020204572726F722052656769737465722052656164204572726F72200A0D000000F8B504462148224E807810287A\n"
+":4070000007D0C00602D401207074F8BD03207074F8BD607821780002084345BA282D02D30A207074F8BDA01CF9F71CFB00BA000A61790002144F08433860A0793871012829\n"
+":4070400002D009207074F8BDE01DF9F70BFB00BA000AA17A00020843B8600C480C4CC5840121206800F02CFA002801D00720F8BD034805218170206800F0FCF90020F8BD17\n"
+":4070800090000020482C00205C2D00201019002084000020F8B504000AD0284E2848B17810290BD0C90605D4012141720846F8BD0220F8BD032141720846F8BD61782278A4\n"
+":4070C000090211434DBA0A21062D02D341720A20F8BD1C4F0121386800F0F2F9002801D00720F8BDA01CF9F7BDFA00BA010A60790902014314480160E179A27909021143A7\n"
+":4071000049BA4160617A227A0902114349BA8160E17AA27A0902114349BAC160617B227B0902114349BA0161084845840420B070386800F09FF90020F8BD000090000020B0\n"
+":40714000482C002084000020482D00201019002070B50E4C0325A078102808D0C1060C4802D40121017209E00572032070BD094E0121306800F0A4F9002801D0012070BD0F\n"
+":40718000A570306800F076F9002070BD90000020482C00208400002070B50F4CA078102809D0C1060D4802D40121C1710AE00321C171084670BD0A4D0121286800F080F972\n"
+":4071C000002801D0012070BD0220A070286800F051F9002070BD000090000020482C00208400002070B50C4C0825A078112803D00A488575082070BD094E0121306800F0A7\n"
+":407200005FF9002801D0072070BDA570306800F031F9002070BD000090000020482C00208400002070B5224E0446B1782148102909D0C90603D40121C174084670BD03218E\n"
+":40724000C174084670BD61782278090211431A4D49BA6980A1782972012907D0022907D0042914D00221C174084670BDE07804E02079E1780002084340BA104C68600121E3\n"
+":40728000206800F01DF900280AD0072070BDE01CF9F7E8F900BA000AA17900020843ECE70620B070206800F0E5F8002070BD000090000020482C0020101900208400002006\n"
+":4072C00092B03F493D488860002080F3108862B6FAF778F9FDF75CF9FCF7B0FEFCF7B2FDFCF706FEFCF72EFEFCF776FEFCF752FE3448C26A02210A43C262C06A324C08403A\n"
+":40730000009008200D9001200E900320002510900F950DA92046F9F7FDFC002208212046F9F7C3FD2948C069009029480368C12228492948FDF7C0FC28A22BA12DA0FDF775\n"
+":40734000BBFCF9F7CDF91F4C40342069400002D50120F9F719FC20690121C90508432061FCF788FE2B4C20222B486169F9F756F90520A0810BA80B9500F063F82062012180\n"
+":407380000CA80C9500F062F8124960621422083101A8F9F743F9002101A800F0CDF80D49A06114221C3106A8F9F738F9002106A800F0C2F8E06100F03FF8FEE700040008D3\n"
+":4073C00000ED00E000100240000400500020024000000140208B0008BC10020831363A33383A3135000000004E6F762032372032303139004275696C64204461746520618B\n"
+":407400006E642054696D653A202573202573200A0D00000060000020B818002001460020842900D0C81C704710B5002800D1012000F0EEFE002010BD10B500F057FF002028\n"
+":4074400010BD10B5012000F0D5FF10BD10B5012901D0002010BD03220021012000F0DCFF040004D000231A46194601F0C9F8204610BD000038B5002405460094FFF732F939\n"
+":4074800000280FD06946284601F046F9012801D0FF2038BD009800280DD0012007490007486008E000231A461946284601F0A8F8012800D0FF24204638BD000000ED00E0A0\n"
+":4074C00038B5054600200090002D11D00024481C10D0002900D00C46FFF704F9002814D06A460021284601F051F9012815D104E0802038BD0024E443EEE7009800280ED024\n"
+":40750000012008490007486009E0002322461946284600F0A3FF012801D0FF2038BD002038BD000000ED00E010B501F0BDF9012801D000F04DFF10BD3EB5044608200D4640\n"
+":40754000205EFFF76BFF02A901910090208A2B4682B22168606801F07FF9012801D000203EBD02983EBD10B500F046FE002010BDFFB5044689B000276846878007821D46C8\n"
+":4075800016460297002C11D00A98C4420ED02178432903D0F2A0FDF78FFB07E0F84861780278914205D0F7A0FDF786FB02200DB0F0BD0A980B00C01E0390F94880880790A3\n"
+":4075C0000A982218F748203A0078FDF785FB180D2A67AAFDFCFBFAF9F8D8F7F7F7F7F7F6F5F4F3F2F1F0EFF7012802D0022804D085E201204003608029E0EB4902980A5CD4\n"
+":40760000201882700298401C02902028F6D32021A01CFEF76FFE029961188870CF7024203AE0012802D002281DD068E201A90020FFF79EFA002804D0DCA0FDF73DFB684679\n"
+":407640000782684680880102000A014361800221A01CFEF74FFE2071677106203080D1490220087079E101A904A8FFF781FA0290002804D0CDA0FDF71FFB68460782684676\n"
+":40768000008A010AA170E0700221A01CFEF732FE2071029860710620308072E2012802D0022826D06DE20592D17F0398029181B2A01CFEF71FFE0299814207D005980A99B5\n"
+":4076C000C27FC2A0C91EFDF7F7FA39E0E178A27808021043B24940BA8880002201A9FFF787FA40E0684681880802090A0843608081E0A21C01A90798FFF77AFA94E06946DE\n"
+":407700008988A01CFEF7F6FD69468988611888706946898802986118C87069468888001D71E0012802D0022823D02AE2D17F0398029181B2A01CFEF7DDFD0299814207D096\n"
+":40774000ADA0FDF7B9FA6846878002200290C9E7E178A27808021043914940BA8880002201A9FFF73BF902900028BBD068468780B8E7A21C01A90798FFF730F954E001283E\n"
+":4077800002D002284BD0FCE1D17F0398029181B2A01CFEF7AFFD0299814216D096A0FDF78BFA68468780022002901EE0D7E1D3E1CFE1C4E1B5E166E156E18EE0E3E17AE00C\n"
+":4077C00076E072E06EE041E03AE0E178A27808021043734940BA8880002201A9FFF778F90290002801D068468780684680880102000A014361800221A01CFEF77BFD207192\n"
+":40780000029860710620308066480178012912D002298AD068468088002886D06FE1A21C01A90798FFF754F90290002800D166E76846878063E76946898800297ED1A0E1F1\n"
+":40784000FFF71CFB57480770378056E154484088002810D070A0FDF72FFAFF20A070504841880A0AE270217103216A46918002210291478004E001A9A01CFEF7F5FF0290AF\n"
+":4078800069468988A01CFEF735FD69468988611888706946898802986118C87069468888001DF9E6FEF7B8FF6AE1FFF775FC67E1FFF74EFC64E1D17F0398029181B2A01C96\n"
+":4078C000FEF718FD0299814203D04BA0FDF7F4F94FE1A01CFFF7DEFB52E1012802D002283DD00CE1D17F0398029181B2A01CFEF701FD0299814207D03FA0FDF7DDF9684688\n"
+":4079000087800220029012E0E178A27808021043234940BA8880002201A9FFF70DF80290002804D043A0FDF7C7F968468780684680880102000A0143618000E00BE00221E5\n"
+":40794000A01CFEF7D7FC207102986071CDE06946898800297CD0022101702F80CFE078E020496E76616C6964205369676E617475726520307825303278202121200A0D0042\n"
+":4079800065000020204944203D2030782530327820213D20307825303278200A0D0000008800002066000020B81800204572726F7220696E2047657474696E672053656E9E\n"
+":4079C000736F72204944200A0D00000020435243204C656E677468203D203078253032782C206F72696720637263203D20307825303278200A0D000020435243207665729C\n"
+":407A0000696669636174696F6E204572726F72202121200A0D0000004572726F7220696E204D435520697473656C66202121200A0D0000004572726F7220696E2047657446\n"
+":407A400074696E67204374726C200A0D0000000052E0A21C01A90798FEF76EFF0290002800D10DE7494857E0D17F0398029181B2A01CFEF73FFC0299814200D025E7A01CF3\n"
+":407A8000FFF7B8FA7CE0012802D0022839D036E0D17F0398029181B2A01CFEF72BFC0299814202D039483C380FE0E178A27808021043374A40BAD08021791170002301AA5D\n"
+":407AC000FFF73CFA002804D032A0FDF7F5F868468780684680880102000A014361800221A01CFEF707FC20716771062030802F480178012900D12AE7077005202880002098\n"
+":407B000055E52348A31C017801AAC088FFF716FA02900028A5D01FA0FDF7CEF868468780AEE6D17F0398029181B2A01CFEF7E2FB02998142A2D1A01CFFF774FB20E01CA091\n"
+":407B4000FDF7BAF8204921A0FDF7B6F8F8F75AFF16E0FFF7CBF913E0FFF744FB10E0D17F0398029181B2A01CFEF7C4FB0299814203D007491D48488002E0A01CFEF72AFEF9\n"
+":407B800037800A48B8E7092011E50000347A0008880000204572726F7220696E205265616420495350200A0D00000000660000204657205570647420496E69746961746589\n"
+":407BC00064200A0D00000000050A0008204669726D776172655F757064617465203D20307825303878200A0D000000000A200000F8B5134C0F46E66805462068001D00F07A\n"
+":407C000069FA681C07D1002F05D021680D48091D00F098FAF8BD2068751945602168B54204D2A06B091D00F075FAF8BD606B091D00F070FAA06A8542F7D2A562F8BD00004F\n"
+":407C40000C00002098010020F8B5054600F086FA2A4CA068401CA0602068294F002803D06069002827D02CE02560A068012828D1002614207043C01900F03EFA761C072E6A\n"
+":407C8000F7D31F488C3000F037FA1D48A03000F033FA1B48B43000F02FFA1948C83000F02BFA1748DC3000F027FA15488C3060631430A06305E02068E96AC06A884200D86B\n"
+":407CC0002560606A401C60626864E86A2169884200D9206114214843C019291D00F032FA00F048FA6069002806D02068E96AC06A884201D200F080FAF8BD00000C0000206A\n"
+":407D0000BC00002070B5114E114C18E000F014FB3068002817D000F09BFE00F01FFAF068C568281D00F0D6F9A068401EA0606068401E606000F01EFA284600F056F8606805\n"
+":407D40000028E3D170BD00F083FEF8E7840100200C00002010B5026C0C46002A0CD0C1688B18C36041688B4201D2194601E00168C1602046F8F752FC10BDF8B5856B1746E2\n"
+":407D800004460026026C002A11D0002F19D0E068F8F744FCE168206C091AE1602268914202D26168081AE060022F17D019E02068002816D1606800F0E5FD06460020606048\n"
+":407DC0000FE0A068F8F72AFC216CA0684018A0606168884205D32068A06002E0002D00D06D1E6D1CA5633046F8BD10B50446006B00F0CEF9204600F0CBF910BD03210E48DF\n"
+":407E00008902420705D0C01DC0080B4AC000821A891A0A4A0023411809C20839C908C900183A11604B600B600B1A0AC093600120C0075360D0607047AC01002058000020A8\n"
+":407E4000044CFFF75FFF20680128FAD900F0D4F9F7E70000BC000020FFB581B097000C9C0E460A9DA5223946206BF8F7E9FB206B3F1FC019C708FF00780701D072B6FEE7B3\n"
+":407E80002218315C20321175315C002902D0401C1028F5D32046403000260090C670072D00D30625E5622665201DE56400F02FF92046183000F02BF924610720401B64624C\n"
+":407EC000A0616665009806763846049A019900F0F1F820600B98002800D0046005B0F0BD30B5114900E011460A688242FBD34B685C18844203D1406818184860084643687E\n"
+":407F00001C18944209D1084C103C2468A24209D052689A1842600A6812680260814200D0086030BD0460F9E75800002010B5044600F014F9A06B002804D0002400F01AF93A\n"
+":407F4000204610BD0124F9E70648416B0968002905D0416BC968C9684968816270470021C943FAE70C00002003480068401C72B600D0FEE7FEE7000008000020F8B50446DD\n"
+":407F800000F0ECF8254640350526AE57274624370BE0606A00280AD0384600F027FD002801D000F04DF9761E76B2002EF1DC0027FF436F7100F0DEF800F0D0F80426AE57F0\n"
+":407FC0002046103000900BE0206900280AD0009800F00CFD002801D000F032F9761E76B2002EF1DC2F7100F0C5F8F8BDF8B50546002700F0A1F9284E3068002801D1FFF7D0\n"
+":40800000FDFEF06805423FD1002D3DD00835680708D06807400F0821081A4519680701D072B6FEE7002D2FD0706885422CD81A48103001460C6801E020460C466168A942AB\n"
+":4080400002D221680029F7D131688C421CD007682168016060680837411B102908D96019420701D072B6FEE741606560FFF738FF61687068401A7060B268904200D2B060BD\n"
+":40808000F0680143002003C400F0E2FC780701D072B6FEE73846F8BD4800002004490868002803D00868026D521C0265086870470C00002010B50124031F24061C601B1FCC\n"
+":4080C0001960191F024B0B60143940380A6010BD697F00084368826801699A60836842685A604A68824201D182684A60002202610868401E08607047014608310022416052\n"
+":40810000D243C1608260016100210160704700210161704730B50B685A1C02D00246083202E0026904E02246546825689D42FAD953684B6099608A60516008610168491C6B\n"
+":40814000016030BD42684A6093688B6093685960916008610168491C0160704772B604480168491C0160BFF34F8FBFF36F8F70470800002005490868002804D0401E086041\n"
+":4081800000D162B6704772B6FEE700000800002070B500281AD004460D4D083C6068E968084201D172B6FEE72268002A01D072B6FEE78843606000F0BFF8606869684018D4\n"
+":4081C00068602046FFF78CFE00F042FC70BD00004800002010B506487D21C9000068F8F7C3F90449401E48610720086110BD00000000002000E000E00120044900074860D3\n"
+":40820000BFF34F8FBFF36F8F7047000000ED00E010B502000FD00948006B002801D072B6FEE700F089F800211046FFF7E1FC00F00FFC002801D1FFF7DFFF10BD0C00002095\n"
+":4082400001490120C86170470C00002010B50C46002809D0054909681831FFF75BFF01212046FFF7C5FC10BD72B6FEE70C00002070B5040025D0154DE06A2968C96A88427A\n"
+":408280001FD2A069002804DB28680721C06A081AA061E06A14220E4E504361698019814210D1201DFFF716FF2868C06AE0622969884200D92861142148438019211DFFF7B3\n"
+":4082C00041FF70BD2868C06AE06270BD0C000020BC000020002805D003490A6A0260C9684160704772B6FEE70C0000201CB50E4800240190234680220CA100940D4800F092\n"
+":40830000ABFA012803D0401C0CD172B6FEE772B600210548C9432C38816201214161C46000F03EF81CBD00003800002049444C4500000000417E00080248016B491C0163CA\n"
+":40834000704700000C00002010B51348016B002902D00121C16110BD0021C16101690F4A02E0002915D0491E14234B43D358002BF7D014234B439A18536814465B680834B8\n"
+":408380005360A34201D15B685360DA680260016110BD72B6FEE700000C000020BC00002010B50948016AFF22120411430162016A120211430162FFF70DFF04490020086079\n"
+":4083C000F8F788F8002010BD00ED00E00800002010B5F8F793F8044600F076FA002803D001200349000748602046F8F78BF810BD00ED00E010B502460021012000F00CF877\n"
+":40840000041E07D00021416001600B460A46C16000F0F6F8204610BDF8B517460E46050016D0002E16D070435030FFF7DFFD04000CD020465030002E0ED0206026642046A9\n"
+":408440000121E56300F0A6F84C2007552046F8BD72B6FEE70020E7E72460EFE7FFB5002583B0040003D00498002802D006E072B6FEE7206C002801D072B6FEE700F014FAD0\n"
+":408480000026002804D10598002801D072B6FEE7FFF764FEA76B002F26D0E56820460499FFF758FC0698002810D0E560606A002807D02046243000F099FA002801D0FFF7ED\n"
+":4084C0009BFEFFF757FE012007B0F0BD7F1EA7632068002802D1FFF7E1FD606020690028EFD020461030E6E70598002802D0002D03D006E0FFF73EFE27E06846FFF7EAFE30\n"
+":408500000125FFF737FEFFF717FFFFF727FE2046403004214156491C00D1067105214156491C00D14671FFF725FE05A9684600F069F9002820460AD0FFF720FD00F088FA26\n"
+":408540002046FFF7F3FC0028A2D00020BCE7FFF7EDFC002818D02068002806D1FFF7FEFD6068FFF785FEFFF705FE204624300599FFF76CFE2046FFF701FD00F069FA002825\n"
+":4085800086D1FFF739FE83E72046FFF7F7FC00F05FFA7DE770B50D46040025D0FFF7DEFD216CE06B48432168411861600021A1632168A160E06B216C401E48432168411837\n"
+":4085C000E1600021C94320464030017141713038002D0BD0FFF790FD20462430FFF78CFDFFF7C8FD012070BD72B6FEE721690029F6D000F0FBF90028F2D0FFF7FDFDEFE7C4\n"
+":40860000FFB5002683B01D46040003D00498002802D006E072B6FEE7206C002801D072B6FEE7022D04D1E06B012801D072B6FEE700F03AF90027002804D10598002801D0A5\n"
+":4086400072B6FEE7FFF78AFDA06BE16B884207D3022D05D00598002817D0002E18D01BE02A4620460499FFF788FB616A002903D02046243000F0BAF9002801D0FFF7BCFDFC\n"
+":40868000FFF778FD012007B0F0BDFFF773FD22E06846FFF71FFE0126FFF76CFDFFF74CFEFFF75CFD2046403004214156491C00D1077105214156491C00D14771FFF75AFD54\n"
+":4086C00005A9684600F09EF8002806D02046FFF755FC00F0BDF90020D5E7FFF73FFDA06BE16B884210D1FFF745FD204610300599FFF7ACFD2046FFF741FC00F0A9F90028C9\n"
+":40870000A0D1FFF779FD9DE7FFF734FD2046FFF735FC00F09DF995E770B50D46040004D0206C002803D072B6FEE772B6FEE72068002804D16068002801D072B6FEE7F7F7F0\n"
+":40874000DDFEA26B0646E06B904219D92146403105200856521CA263421C03D0401C487101240EE0606A0028FAD02046243000F03DF90028F4D0002DF2D001202860EFE799\n"
+":4087800000243046F7F7BEFE204670BDF7B582B0040003D00398002802D006E072B6FEE7206C002801D072B6FEE7F7F7A7FE0090A66B002E1FD020464030042545570746DA\n"
+":4087C00020460399FFF7C6FA761EA663681C03D06D1C3D7101240FE020690028FAD02046103000F003F90028F4D004980028F1D001210160EEE700240098F7F783FE20461B\n"
+":4088000005B0F0BD70B50D4604001AD0002D1AD0FFF7A4FC0F4AD1682868431C0FD02368126A934202D062688A420ED96268891A81420AD2401A28602046FFF74BFD002482\n"
+":4088400004E072B6FEE772B6FEE70124FFF792FC204670BD0C000020FFB585B0164690000F9FFFF7C3FB05001AD05C20FFF7BEFB040012D0256300210E9803910197009050\n"
+":4088800002943246089B06990598FFF7E5FA2046FFF7DAF9012009B0F0BD2846FFF778FC0020C043F7E7000006484169002904D0006B002803D0002070470120704702203B\n"
+":4088C000704700000C000020F8B52C4C0027206B002808D0A069401CA061E069002800D001273846F8BDE668761CE6600ED1606B0068002801D072B6FEE7606BA16B6163E3\n"
+":40890000A063206A401C2062FFF71EFBA06A86420AD3606B0068002810D0606BC068C568686886420DD2A06220681421C06A4843134908580128D0D90127CEE70020C0433A\n"
+":40894000F1E7281DFFF7C6FBA86A002803D028461830FFF7BFFBE86A2169884200D920611421484306494018291DFFF7EBFBE86A2168C96A8842CCD30127CAE70C000020AB\n"
+":40898000BC00002070B500210446002828D0154D2868844201D072B6FEE7206D002808D0401E2065E36CE26A9A4219D0002802D016E072B6FEE7201DFFF78CFBE06C07219A\n"
+":4089C000E062081AA061E06A2969884200D928611421484304494018211DFFF7B3FB0121084670BD0C000020BC00002070B5C068C468002C0BD0204618300646FFF76AFB49\n"
+":408A0000114D286B002804D0314610480FE072B6FEE7201DFFF75EFBE06A2969884200D92861142148430949B4394018211DFFF789FBE06A2968C96A884202D90120E861BE\n"
+":408A400070BD002070BD00000C00002070010020F8B5284C0025206B2E46002808D0FFF77DFB206B401E2063206B002802D03DE072B6FEE7A168204F00291DD136E0F868EC\n"
+":408A8000C56828461830FFF725FB281DFFF722FBE86A2169884200D92061142148431649B4394018291DFFF74DFBE86A2168C96A884201D30120E06138680028DFD1002DCA\n"
+":408AC00001D0FFF741FAA569002D09D00127FFF7FBFE002800D0E7616D1EF8D10020A061E069002802D00126FFF786FBFFF742FB3046F8BD0C000020700100200000000098\n"
+":408B0000000000000102030406070809030406080C1018203000000000010203040000006D61696E0000000010110208194400080000000000000000000100000411020815\n"
+":408B4000DD330008000000000000000080000000537461727444656661756C745461736B0048414C5F4932435F536C617665547843706C7443616C6C6261636B0048414C6A\n"
+":408B80005F4932435F536C617665527843706C7443616C6C6261636B0048414C5F4932435F4572726F7243616C6C6261636B0048414C5F4932435F4164647243616C6C62C2\n"
+":408BC00061636B0048414C5F4932435F4C697374656E43706C7443616C6C6261636B0048414C5F4932435F4D656D547843706C7443616C6C6261636B0048414C5F49324318\n"
+":408C00005F4D656D527843706C7443616C6C6261636B0048414C5F4932435F41626F727443706C7443616C6C6261636B0048414C5F4750494F5F455854495F43616C6C622A\n"
+":408C400061636B004669726D776172655F557064617465004F7074696F6E4279746550726F6700424642325F636865636B5F656E61626C6500000000555956598002E00142\n"
+":408C800001007800010000000000000000000000555956590005D00201005000010000000000000000000000555956598007380401003C0001000000000000000000000056\n"
+":408CC00055595659000F700801001E00010000000000000000000000555956590010700801001E00010000000000000000000000555956596010300C01001300010000004D\n"
+":408D00000000000000000000555956598002E00101007800010000000000000000000000555956590005D00201005000010000000000000000000000555956598007380453\n"
+":408D400001003C0001000000000000000000000055595659000F700801001E00010000000000000000000000555956590010700801001E00010000000000000000000000AC\n"
+":408D8000555956596010300C010013000100000000000000000000000009980001000000F1FFFFFF0F000000000000000100000000000000000000000000000000000000F5\n"
+":408DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073\n"
+":408E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004272696768746E65737300000000000019\n"
+":408E400000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D1\n"
+":408E800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B2\n"
+":408EC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072\n"
+":408F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031\n"
+":408F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1\n"
+":408F800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1\n"
+":408FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071\n"
+":409000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030\n"
+":4090400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0\n"
+":4090800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0\n"
+":4090C0000000000000000000000000000000000000000000000000000109980001000000000000001E000000040000000100000000000000000000000000000000000000AA\n"
+":40910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F\n"
+":40914000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436F6E74726173740000000000000000A1\n"
+":40918000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008E\n"
+":4091C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F\n"
+":40920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E\n"
+":4092400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EE\n"
+":4092800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AE\n"
+":4092C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006E\n"
+":40930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D\n"
+":4093400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ED\n"
+":4093800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AD\n"
+":4093C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006D\n"
+":409400000000000000000000000000000000000000000000000000000209980001000000000000003C00000012000000010000000000000000000000000000000000000039\n"
+":4094400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC\n"
+":4094800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053617475726174696F6E00000000000082\n"
+":4094C000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004B\n"
+":40950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B\n"
+":4095400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB\n"
+":4095800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB\n"
+":4095C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B\n"
+":40960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A\n"
+":4096400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA\n"
+":4096800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA\n"
+":4096C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A\n"
+":409700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029\n"
+":409740000000000000000000000000000000000000000000000000000C09980001000000000000000100000001000000010000000000000000000000000000000000000038\n"
+":4097800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9\n"
+":4097C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057686974652042616C616E6365204175CC\n"
+":40980000746F000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043\n"
+":4098400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8\n"
+":4098800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8\n"
+":4098C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068\n"
+":409900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027\n"
+":4099400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7\n"
+":4099800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7\n"
+":4099C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067\n"
+":409A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026\n"
+":409A400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6\n"
+":409A80000000000000000000000000000000000000000000000000001A099800010000000A00000010270000881300000A0000000000000000000000000000000000000004\n"
+":409AC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066\n"
+":409B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057686974652042616C616E636520546585\n"
+":409B40006D706572617475726500000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EF\n"
+":409B800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5\n"
+":409BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065\n"
+":409C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\n"
+":409C400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4\n"
+":409C800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4\n"
+":409CC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064\n"
+":409D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023\n"
+":409D400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3\n"
+":409D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3\n"
+":409DC000000000000000000000000000000000000000000000000000100998000100000028000000F4010000DC0000000100000000000000000000000000000000000000B7\n"
+":409E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022\n"
+":409E400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047616D6D610000000000000000000000FF\n"
+":409E80000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081\n"
+":409EC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062\n"
+":409F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021\n"
+":409F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1\n"
+":409F800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1\n"
+":409FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061\n"
+":40A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\n"
+":40A0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0\n"
+":40A0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0\n"
+":40A0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060\n"
+":40A100000000000000000000000000000000000000000000000000001309980001000000010000003200000006000000010000000000000000000000000000000000000030\n"
+":40A1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF\n"
+":40A180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004761696E00000000000000000000000020\n"
+":40A1C000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E\n"
+":40A20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E\n"
+":40A2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DE\n"
+":40A28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E\n"
+":40A2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005E\n"
+":40A30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D\n"
+":40A3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DD\n"
+":40A38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D\n"
+":40A3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005D\n"
+":40A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C\n"
+":40A440000000000000000000000000000000000000000000000000001409980001000000000000000100000000000000010000000000000000000000000000000000000024\n"
+":40A48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009C\n"
+":40A4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000486F72697A6F6E74616C20466C69700087\n"
+":40A500000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019\n"
+":40A5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DB\n"
+":40A58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009B\n"
+":40A5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005B\n"
+":40A60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A\n"
+":40A6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA\n"
+":40A68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A\n"
+":40A6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A\n"
+":40A700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019\n"
+":40A7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D9\n"
+":40A7800000000000000000000000000000000000000000000000000015099800010000000000000001000000000000000100000000000000000000000000000000000000E0\n"
+":40A7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059\n"
+":40A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566572746963616C20466C697000000033\n"
+":40A8400000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D6\n"
+":40A880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098\n"
+":40A8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058\n"
+":40A900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017\n"
+":40A9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D7\n"
+":40A980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097\n"
+":40A9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057\n"
+":40AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016\n"
+":40AA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D6\n"
+":40AA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096\n"
+":40AAC0000000000000000000000000000000000000000000000000001B09980001000000010000007F00000010000000010000000000000000000000000000000000000008\n"
+":40AB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015\n"
+":40AB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053686172706E657373000000000000001E\n"
+":40AB80000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074\n"
+":40ABC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055\n"
+":40AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014\n"
+":40AC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4\n"
+":40AC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094\n"
+":40ACC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054\n"
+":40AD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013\n"
+":40AD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D3\n"
+":40AD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093\n"
+":40ADC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053\n"
+":40AE000000000000000000000000000000000000000000000000000001099A000100000000000000020000000000000000000000000000000000000000000000000000006B\n"
+":40AE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D2\n"
+":40AE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004578706F73757265204175746F0000007E\n"
+":40AEC0000000000000000000000000000000000003000346756C6C20464F56204175746F204D6F646500000000000000000000000000004D616E75616C204D6F646500004D\n"
+":40AF000000000000000000000000000000000000000000524F49204261736564204175746F204D6F64650000000000000000000000000000000000000000000000000000CA\n"
+":40AF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D1\n"
+":40AF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091\n"
+":40AFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051\n"
+":40B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\n"
+":40B0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D0\n"
+":40B080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090\n"
+":40B0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050\n"
+":40B10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F\n"
+":40B1400000000000000000000000000000000000000000000000000002099A000100000001000000102700004D0100000100000000000000000000000000000000000000A2\n"
+":40B18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008F\n"
+":40B1C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004578706F73757265204162736F6C7574FA\n"
+":40B200006500000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088\n"
+":40B2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CE\n"
+":40B28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008E\n"
+":40B2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E\n"
+":40B30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D\n"
+":40B3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CD\n"
+":40B38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D\n"
+":40B3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004D\n"
+":40B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C\n"
+":40B4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC\n"
+":40B4800000000000000000000000000000000000000000000000000026099A000100000000000000FFFF0000808000000100000000000000000000000000000000000000C3\n"
+":40B4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C\n"
+":40B50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000524F49204578706F7375726500000000A6\n"
+":40B5400000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA\n"
+":40B58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008B\n"
+":40B5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004B\n"
+":40B60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A\n"
+":40B6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA\n"
+":40B68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A\n"
+":40B6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004A\n"
+":40B700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009\n"
+":40B7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C9\n"
+":40B780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089\n"
+":40B7C0000000000000000000000000000000000000000000000000000D099A00010000006400000020030000640000000100000000000000000000000000000000000000AC\n"
+":40B800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008\n"
+":40B840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A6F6F6D00000000000000000000000023\n"
+":40B880000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067\n"
+":40B8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048\n"
+":40B900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007\n"
+":40B9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C7\n"
+":40B980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087\n"
+":40B9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047\n"
+":40BA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006\n"
+":40BA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C6\n"
+":40BA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086\n"
+":40BAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046\n"
+":40BB000000000000000000000000000000000000000000000000000008099A0001000000C01CF6FF40E309000000000001000000000000000000000000000000000000005B\n"
+":40BB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C5\n"
+":40BB800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050616E0000000000000000000000000066\n"
+":40BBC0000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\n"
+":40BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004\n"
+":40BC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C4\n"
+":40BC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084\n"
+":40BCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044\n"
+":40BD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\n"
+":40BD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3\n"
+":40BD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083\n"
+":40BDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043\n"
+":40BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n"
+":40BE400000000000000000000000000000000000000000000000000009099A0001000000C01CF6FF40E3090000000000010000000000000000000000000000000000000017\n"
+":40BE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082\n"
+":40BEC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054696C74000000000000000000000000A5\n"
+":40BF000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0\n"
+":40BF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C1\n"
+":40BF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081\n"
+":40BFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041\n"
+":40C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
+":40C0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0\n"
+":40C080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080\n"
+":40C0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040\n"
+":40C1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF\n"
+":40C1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BF\n"
+":40C1800000000000000000000000000000000000000000000000000028099A00010000000000000005000000000000000000000000000000000000000000000000000000AE\n"
+":40C1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003F\n"
+":40C2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069484452000000000000000000000000B7\n"
+":40C24000000000000000000000000000000000000300064844522044697361626C65000000000000000000000000000000000000000000484452204175746F00000000006C\n"
+":40C28000000000000000000000000000000000000000004844522031580000000000000000000000000000000000000000000000000000484452203258000000000000006F\n"
+":40C2C0000000000000000000000000000000000000000048445220345800000000000000000000000000000000000000000000000000004844522038580000000000000026\n"
+":40C3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FD\n"
+":40C3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BD\n"
+":40C38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007D\n"
+":40C3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003D\n"
+":40C4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC\n"
+":40C4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC\n"
+":40C48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007C\n"
+":40C4C0000000000000000000000000000000000000000000000000002A099A000100000000000000020000000100000000000000000000000000000000000000000000006B\n"
+":40C5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FB\n"
+":40C540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004672616D652053796E6300000000000013\n"
+":40C580000000000000000000000000000000000003000344697361626C65204672616D652053796E6300000000000000000000000000004672616D652053796E63203330CE\n"
+":40C5C000487A00000000000000000000000000000000004672616D652053796E63203630487A00000000000000000000000000000000000000000000000000000000000089\n"
+":40C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA\n"
+":40C6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA\n"
+":40C68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A\n"
+":40C6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A\n"
+":40C7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F9\n"
+":40C7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9\n"
+":40C780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079\n"
+":40C7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039\n"
+":40C8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F8\n"
+":40C8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B8\n"
+":40C880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078\n"
+":40C8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038\n"
+":40C9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7\n"
+":40C9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B7\n"
+":40C980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077\n"
+":40C9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\n"
+":40CA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6\n"
+":40CA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6\n"
+":40CA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076\n"
+":40CAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036\n"
+":40CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5\n"
+":40CB400000000000000000000000000000000000000000000000000024099A0001000000080000004000000008000000080000000000000000000000000000000000000095\n"
+":40CB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075\n"
+":40CBC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000524F492057696E646F772053697A6500F8\n"
+":40CC000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D3\n"
+":40CC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4\n"
+":40CC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074\n"
+":40CCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034\n"
+":40CD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3\n"
+":40CD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B3\n"
+":40CD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073\n"
+":40CDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033\n"
+":40CE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F2\n"
+":40CE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B2\n"
+":40CE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072\n"
+":40CEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032\n"
+":40CF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1\n"
+":40CF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1\n"
+":40CF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071\n"
+":40CFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031\n"
+":40D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0\n"
+":40D0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0\n"
+":40D080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070\n"
+":40D0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030\n"
+":40D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EF\n"
+":40D1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AF\n"
+":40D18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F\n"
+":40D1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F\n"
+":40D2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EE\n"
+":40D2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AE\n"
+":40D28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006E\n"
+":40D2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E\n"
+":40D3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ED\n"
+":40D3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AD\n"
+":40D38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006D\n"
+":40D3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D\n"
+":40D4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC\n"
+":40D4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AC\n"
+":40D48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C\n"
+":40D4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C\n"
+":40D5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB\n"
+":40D5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB\n"
+":40D58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B\n"
+":40D5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B\n"
+":40D6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA\n"
+":40D6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA\n"
+":40D68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A\n"
+":40D6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A\n"
+":40D7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9\n"
+":40D7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9\n"
+":40D780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069\n"
+":40D7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029\n"
+":40D8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8\n"
+":40D8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8\n"
+":40D880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068\n"
+":40D8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028\n"
+":40D9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7\n"
+":40D9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7\n"
+":40D980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067\n"
+":40D9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027\n"
+":40DA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6\n"
+":40DA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6\n"
+":40DA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066\n"
+":40DAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026\n"
+":40DB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5\n"
+":40DB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5\n"
+":40DB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065\n"
+":40DBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025\n"
+":40DC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4\n"
+":40DC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4\n"
+":40DC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064\n"
+":40DCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\n"
+":40DD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3\n"
+":40DD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3\n"
+":40DD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063\n"
+":40DDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023\n"
+":40DE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2\n"
+":40DE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2\n"
+":40DE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062\n"
+":40DEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022\n"
+":40DF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1\n"
+":40DF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1\n"
+":40DF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061\n"
+":40DFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021\n"
+":40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0\n"
+":40E0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0\n"
+":40E080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060\n"
+":40E0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\n"
+":40E1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF\n"
+":40E14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009F\n"
+":40E18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005F\n"
+":40E1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F\n"
+":40E2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DE\n"
+":40E24000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E\n"
+":40E28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005E\n"
+":40E2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E\n"
+":40E3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DD\n"
+":40E34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D\n"
+":40E38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005D\n"
+":40E3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D\n"
+":40E4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DC\n"
+":40E44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009C\n"
+":40E48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005C\n"
+":40E4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C\n"
+":40E5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DB\n"
+":40E54000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009B\n"
+":40E58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005B\n"
+":40E5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B\n"
+":40E6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA\n"
+":40E64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A\n"
+":40E68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A\n"
+":40E6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A\n"
+":40E7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D9\n"
+":40E740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099\n"
+":40E780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059\n"
+":40E7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019\n"
+":40E8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D8\n"
+":40E840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098\n"
+":40E880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058\n"
+":40E8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018\n"
+":40E9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D7\n"
+":40E940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097\n"
+":40E980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057\n"
+":40E9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017\n"
+":40EA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D6\n"
+":40EA40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096\n"
+":40EA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056\n"
+":40EAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016\n"
+":40EB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D5\n"
+":40EB40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095\n"
+":40EB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055\n"
+":40EBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015\n"
+":40EC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4\n"
+":40EC40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094\n"
+":40EC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054\n"
+":40ECC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014\n"
+":40ED000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D3\n"
+":40ED40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093\n"
+":40ED80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053\n"
+":40EDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013\n"
+":40EE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D2\n"
+":40EE40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092\n"
+":40EE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052\n"
+":40EEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012\n"
+":40EF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D1\n"
+":40EF40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091\n"
+":40EF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051\n"
+":40EFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011\n"
+":40F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D0\n"
+":40F040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090\n"
+":40F080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050\n"
+":40F0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\n"
+":40F1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CF\n"
+":40F14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008F\n"
+":40F18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004F\n"
+":40F1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F\n"
+":40F2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CE\n"
+":40F24000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008E\n"
+":40F28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E\n"
+":40F2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E\n"
+":40F3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CD\n"
+":40F34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D\n"
+":40F38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004D\n"
+":40F3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D\n"
+":40F4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC\n"
+":40F44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008C\n"
+":40F48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C\n"
+":40F4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C\n"
+":40F5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB\n"
+":40F54000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008B\n"
+":40F58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004B\n"
+":40F5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B\n"
+":40F6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA\n"
+":40F64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A\n"
+":40F68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004A\n"
+":40F6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A\n"
+":40F7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C9\n"
+":40F740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089\n"
+":40F780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049\n"
+":40F7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009\n"
+":40F8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C8\n"
+":40F840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088\n"
+":40F880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048\n"
+":40F8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008\n"
+":40F9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C7\n"
+":40F940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087\n"
+":40F980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047\n"
+":40F9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007\n"
+":40FA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C6\n"
+":40FA40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086\n"
+":40FA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046\n"
+":40FAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006\n"
+":40FB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C5\n"
+":40FB40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085\n"
+":40FB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045\n"
+":40FBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005\n"
+":40FC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C4\n"
+":40FC40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084\n"
+":40FC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044\n"
+":40FCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004\n"
+":40FD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3\n"
+":40FD40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083\n"
+":40FD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043\n"
+":40FDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\n"
+":40FE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C2\n"
+":40FE40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082\n"
+":40FE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042\n"
+":40FEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n"
+":40FF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C1\n"
+":40FF40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081\n"
+":40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041\n"
+":40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n"
+":020000040801F1\n"
+":4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0\n"
+":400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080\n"
+":400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040\n"
+":4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
+":4001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BF\n"
+":40014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007F\n"
+":40018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003F\n"
+":4001C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF\n"
+":4002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BE\n"
+":40024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007E\n"
+":40028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E\n"
+":4002C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FE\n"
+":4003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BD\n"
+":40034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007D\n"
+":40038000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003D\n"
+":4003C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FD\n"
+":4004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC\n"
+":40044000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007C\n"
+":40048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003C\n"
+":4004C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC\n"
+":4005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BB\n"
+":40054000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007B\n"
+":40058000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003B\n"
+":4005C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FB\n"
+":4006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA\n"
+":40064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A\n"
+":40068000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A\n"
+":4006C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA\n"
+":4007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9\n"
+":400740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079\n"
+":400780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039\n"
+":4007C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F9\n"
+":4008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B8\n"
+":400840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078\n"
+":400880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038\n"
+":4008C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F8\n"
+":4009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B7\n"
+":400940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077\n"
+":400980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\n"
+":4009C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7\n"
+":400A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6\n"
+":400A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076\n"
+":400A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036\n"
+":400AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6\n"
+":400B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B5\n"
+":400B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075\n"
+":400B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035\n"
+":400BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5\n"
+":400C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4\n"
+":400C40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074\n"
+":400C80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034\n"
+":400CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F4\n"
+":400D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B3\n"
+":400D40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073\n"
+":400D80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033\n"
+":400DC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3\n"
+":400E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B2\n"
+":400E40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072\n"
+":400E80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032\n"
+":400EC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F2\n"
+":400F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1\n"
+":400F40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071\n"
+":400F8000000000000000000000000000000000000000000000000000050003CC00000000000003C054A20B3371E40C0071DC00005002022C501C0F00502B000200400006FA\n"
+":400FC000503E00025018FD9A501F0006000000010100000200800000502E010050450002100000335041000280007F0050340800500A020050302080505A0E3E50750003B8\n"
+":401000000CCC0CCC080071CC14085088001150930004000CFFBEFAE1399950A6399950A03FEF507E0199507B00020CCC100050FE00C850F4033350F100020CCC1CCC50FA79\n"
+":40104000014750F700020B33133350EE033350DC012C50C8033350C500020CCC1CCC50D0033350CD000213331CCC50D800A350D5000206660CCC50A8000250BAFFFF50AA94\n"
+":40108000400450B8020C50BD0002640C001852CA017053160147531CFFD8531A0CCC52D60FAE5322200053410002D80004007078000453240C0053280400714B00020400DA\n"
+":4010C0000400551000CC52B700025DE77EEF52BF000401990199019901995539000310001000100053E5000200CC00CC54B201475514040055120080544E0019544C0003EF\n"
+":401100005049000500000000023200CC2000548900088000F8008000FE6709997E6680007E6654A81000300E00BB20090002400040003009000240004000400900024000CF\n"
+":40114000400010128000118D00020080008011670004000000004000400011910003010000800080F039000200003390E00100020001000011870003008100003200601DAE\n"
+":4011800000020000653860164000201001705398370F202E000140100000100900020001FFDD602900020000199A20300014302E00144030001420161E1E30161E1E40168F\n"
+":4011C0001E1E2018001E3018001E4018001E5344004F52AA0000202C03F1302C03F1402C03F111750004FFFFAD42FFFFAEC660180100600C0211604A036C503240002014BF\n"
+":40120000000020010002078004382022041920201E0020250004000082350001046A20050004800080007FFF7FFF301400003001000210700C3030201E003025000400007D\n"
+":4012400082350001046A30220419300E000040140004400100020780043840201E0040250004000082350000823540220419401200507078000460B10010A1F4A224A25469\n"
+":40128000A224A288A2940000A3180000000000000000000000000000000060004F3820100160601620005440000071C203E671C002006025000200300000602D0005002FE4\n"
+":4012C000030000000000400060390005002102000000000040002051001400010008000100080001000200030005000300120003000000010008000000060001002D0001B2\n"
+":40130000002D3055001400010008000100080001000200030005000300120003000000010008000000060001002D0001002D4051001400010008000100080001000200038A\n"
+":401340000005000300120003000000010008000000060001002D0001002D6029000200010000000006000008000100010300A02C0000000000006538380000DF503038CB43\n"
+":401380004086A201AE129A0129AC130EE086F84C89CE069980F26469ABD03B820198C680423E9C5E66103080D20877A5411040C1681E083D6AD65E9C291EF4D5105041409F\n"
+":4013C0004A88115BB47244C938059F46B5887C0F04081520686C0F7028913441634016EC93D90839886882A6882C6902DE8B619EC0099F4329082C69C300C06C1FFD02421F\n"
+":4014000020A9A0C10430301072757105671105403BFD0060EF2163F486D18CA1C56A06F4CF20093E644200181675F6021D43F6200889D161087A7420C66F492E1C800281B7\n"
+":40144000011F4DB010CD842642EF490310C08F461B4CB001463CDAD034C80D5F01F948CC0F1A003F44ED8F83FF04D80040B39A8881B45D90AC0044ECF20529812428203B0B\n"
+":40148000CFC47C8193328006A280DA2C0242083C008D10E00C02835E395026A86FCF67440D1B813093B5454883200E1DFAFC42002CEE8D01C8E9194FDF469F912A4A202671\n"
+":4014C00086BD3BAA21E75697206D4C0985405994A013B00CD42071CC9163D7A8E3DD69A3302DEB0C2437D7D107F7E6C1040D107BC28925BFCC0827E919A11881F081184194\n"
+":4015000016933FCE90287A07BA264C4013B435DF66101C835437ABD10448DEA6D8230F99CD91E8089A00A120059FE61F571D882650041D37B45BFD58823C965841134BD447\n"
+":401540000DE3D12E240610412041D62A8250CB429C00022A695D0C060080447C2AA441C8C150C801C5BA2071710400781DE93DC46A987161196984D88D0248D124F83A700C\n"
+":401580009270689289128C895512A9DEDB458348969EC496F1BB8092D0A8B0CF86CC4496F44148C4812E912F0689309130C8995132C89A5134C89B5136C89C5138C89D51AF\n"
+":4015C0003AC89E513CC89F513FD9A6024FC2A0691410625028FA21784A0F502B8C1001090129348A18B1620D128922899146A28D9148A291914AA295914CA299914EA29D61\n"
+":401600009150A2A19152A2A59154A2A99726613722B122B1915AA2B5915CA2B9915EA2BD8FA19AC60800B480C49A458448B1068962916250FA78D06150348B28312C8A1068\n"
+":401640003A0840F48105022A048D0446A06916706259A9168A2D0A104E082150348B58312D548B6516CC8B7516EC8B85170508290420AA56F9062250348B98312E4A105EC9\n"
+":401680000841848195034A06D566606006236D7E068971CB768F6D141D1E20F97C00D8123539C50824823C13B887886163D1DAA58CB6479092C8036521632820479C929122\n"
+":4016C0001E89447D0A4443D94888FFE7A18282121C7447CCFBC4455BF8406C5FC2450E9DE85481159228575609172C1EDB3D96090E4B805A3F8924618406B370923E9D8080\n"
+":4017000029904921D11D6484B049F5F5217052C1253804015C6C24A748B31508125E28406B490939C0D30A8009400223CDC3A8A02219F0B7511445423E87DE228A6C128BC5\n"
+":40174000A831CA940947C1F40B804C09461C33E6840228E28B83BE09478E1C4A39609464A23DE8EC452058CFA16588A40D11B5A514914202E4900E4D1D00BCE4604A501336\n"
+":40178000CD088814A0823E4902229D2F4A50114FE859A2A74253C70F38B6160A8E5488504254F07E629F84A9F42D410588F2A502F42CE115A0A23E8ADE22B4EC47D0FCC417\n"
+":4017C00058700EC2A042580E88F9A1C08B13A19E951A22C81C67D0B9445983894E425A0C0D4CC25A820D61581E3F493E85CC32E40051D2A0104352825C9688F4DC20B06199\n"
+":401800001808F80DD88C23911F137A11865C23E8CB023128309895002627199E1313AFD18A7A1F58C3504CD18B2E109A384C6C44026470ADA109AA484C8B06084D3A099D21\n"
+":40184000948D3E58A21000D3A043A57FA3729B09BF2C2A3827445084DD0A48274F5D9F158784EA882A5427552613B7D19EC54304EDF444C150813B80C47AACE08EEA502123\n"
+":40188000355C09DF4404264BC886A2C04D5B827B490A8709F83223DAF0847E440F4035CB07ED6609FB32084D4684FE1311F4333080200FA650440AF341F0F3DF21007D491A\n"
+":4018C000472008730C398272C076525D4495F60378000003A8D2380346B1EBCB778422077AE76C7B230848F3FCFF3EBC62AE2110060B9E03B7903A86247B2F38583147039F\n"
+":40190000A410F5C96A076728994810F5ED5A2691D06D821CA65133980D2D81FF451889A471A072A060EEA673EDF38101CFE40E0374011F4C0F27220FA7FF4801E84682F5E5\n"
+":40194000E89895D3C87002A13000329435F37381F7CF60F63D6880E68F5D7E89BDBD8E8F597F0F32CB135068177C5F3E2030E5D9E8665C1C810984020441556F87598A0F9C\n"
+":40198000858EC87A1E8B83BCD9E03187E2AF421E04C1C02FEA54844DE0D6FF401A4750A34ADC20A044186F86447D1A8118800A02BDA31622B0380784E1A74B7491F47804F2\n"
+":4019C00020561540F0EBC0F6E2A8C891370C12978A078F3765102412077D7A2844D0421805FE9FF9236387D389592B186160F2F18AA1B1DADF24041D52331E8DE00CF002FA\n"
+":401A000039932131C2AF07B3230FCE662213861273390753242821009007998B97A4AA07C514231427475CA40835D973E3EA0273A181CD6CC4C524012F3CD098CC0EFAF423\n"
+":401A4000F0420054231047108821A36897BD418032C4AEEF83C4EC31791630F00E51E97D110203A9390DC196F55A22697C308CA0EC8D13B00E394900CFAC91C46A9A4C1612\n"
+":401A80004FC2DFE2454A4C064C27E97683A1A1D45943DF98633A207E0E9CA4B069380C0CF7B2BA8C1B5104009C21AF5F561F869BD4AAC0AAB468F91C1D2F2C218741801435\n"
+":401AC000D00140880387D3480E06078849440308C30ECCE832D0238E33F4781C469F3BAF146881A12A162723F83CE2E3D357A04101A0374E920CCA67E169D2EDE54C83A12C\n"
+":401B0000154BBB4B04431889A28860E98EB53D5A9867B06BC1C513E77C03D90C821B82BC300102E42A1D06B0908207C142B020E0BD450C40F1A88757379B8029DD14A2205E\n"
+":401B400042903AA06C023BF151883CF338736944D80163481C052D3D00D8345B0B038F973DC7A07CC41A2C0584073004534033121E62482E837810650263C191C209836084\n"
+":401B8000D96DDAD3A2059E2408A65CF30A31F4BA90836318B6680563C8E967501E83008C320FEA248C4841AB02317AB3A8674212C13067B2DC86580C0556041F4AC4902656\n"
+":401BC0000D767DD084E3E86A3A8C6129040D82852F49820CD60581B0C1AC6B832690372E1B5B118843E0A218612412317968E9302B070070E86484841028095C8511C46968\n"
+":401C00000251646A8164E84E13069D301E47D8E11E03D045202274282D040E81142C13425A23C0CE0FD75044255EA023C340A75BE921CA3F8BD754880F01104C417694889B\n"
+":401C40008014D8B7CC21070DA37ED6C03D0693905276FD56F434A0C1748011A452A9301C8630681D20018A8D1A9603348104BB5748775D09344C20808203C156307D878BFE\n"
+":401C8000E0449DE6272208FAAE504002589D00EAC821049743B2500417EF6411EC5EF101422AEE1851248D02D82220030EE1791240271C04BF5F79080D58E40B02A88E824E\n"
+":401CC0005F64A508201186140CCA42902024028892069085102530653468FA1D3CF7FDC19F078E07880BCEB2462C0B3260E6213CA3B83D41E840A498818401C402BE392454\n"
+":401D000036004EC8362604C2C4C0DA9BC7B23F082BE91871E12623D4F062247A7B28CF21C07A19CB8198B98633BC7804E9B0F8812E8C00B884044031C42F0A0440DC3EA104\n"
+":401D4000235702C159CEC044551C4630642DA810093B40DA673506A00690902A0A8104C90279949CF8D847018C10B28CD3500C080853E8F98193017A47F710190FE515F381\n"
+":401D8000E10C1CD310455EE1F62970DC8634DC8FB362106AE8583500C2281D18395D9200609C0E8C1EC0BD3ECBEB103042862B750DBC440C0DA1880D3981DEF1661DFF287C\n"
+":401DC000BD4AA62481E404F615F14A4B9B6A0F776889DFC6EBC813E99BA1200793CECCC1EB8DC29884328F2E9A67103BCFE385DCE223202F318408F219F5CC094846790066\n"
+":401E000039CFD73C05C14684CAB83CC7AF23FB0C3917C98EDE34A73E54D02159EC428FE7984E0A02867C4A0031587F9961289D74880FC0A1E3EBD6C3E91531ED4942130A1D\n"
+":401E40001431E0475335901A7992269D5499143873BA7109D0EDB5512D7B50EC79DC1892DDEAFA33E103E169200C767219544A262291A0398D7E2334160D00AB8576110095\n"
+":401E8000500F21E4811B82808203AE491ACD23ECCCF13338F8B6B07CFC8420A1AA10F7ED48F862F4496057BF681025816EFD9F409605E1041AB1725100C01AD0B4AC0728C9\n"
+":401EC0003A6C078E825A0DAAF14016E84532018E6006BE50BAD00E621C013D80002A1C8178F3DFE087B49BA4023A3A70B900048847D80C865A751D30DB5E2E410F50348D6C\n"
+":401F00006705210373C5F70201F8EF586F031602333CB7E0DB2330A1778801A53D470049D62E626C00F6242052D0A36463285CE998F2CDC160E82400D8512392382106E128\n"
+":401F4000A160E437FC0F2E32344B01FBA4560AC5007A84007F9294887102EECC01CC5508D00D45705C5E2980002836AB12028F607440A063418682A011D589CB40603E0754\n"
+":401F8000E0B3A51FCBCA7783DB2BC33DA5831807C108900368490260AA0207A46ECC04188B89C06EB1304A89882FDE7EE33A00126D4DC64D2BCDA8FAFE307A90946190BBBB\n"
+":401FC000D806B184B99600220AA010049DD31073A244801D371807DB6542604DA4082616B01F98084F8C06146172400EE8F6F23A0078844BCEE1CB105E1848448A81C40B80\n"
+":40200000097CC49420ACD6204855351012772BD42A65E0E071334397E8BEB13D41EE868D23C41C36037ACB23F4B0EBA5E9040D613CDA01EE93123D2312EE04704B0F17537F\n"
+":402040001F60FA897405F843BC704189A423E0842F5F629C3008A9F11991243B426C58EA13831BAD4E5DF79A201799A492B3A0598C882282CD8183542A0C00B052CEA166FC\n"
+":4020800090E48FE24150E44D0A148990D5F7C5D0C36268861D291C37272066162090C43D1323A17422162299D6431323A9D6421620A1622A9A014E3F702C03FE2A0867486A\n"
+":4020C00069E2CCE4CD109BB8E044402447AEA08D113B806F960F6120F1DC94400C45D448592C080EDBC62310B116BC9A84993C1A21DCDC020CF4370085074116051DD80AA4\n"
+":4021000000D005CD0060A6380A6284083881DE07A42009CA1A77689205D03BE8FB612437F939EE7704393EF0841EB60C210803BFD22BC00FF3BB831621C380900E3BEAC805\n"
+":4021400080447B979081D0D11BD4081E2130A90830212001C608EC4C25D21405E16EE13400DE192457ED01A40614406546C7820247B8EFC7B24184091E055F26CB0840058B\n"
+":402180001F3D185E3E9AC340074E732E8A184FD63647EB1FA43D5E44C0E45C615C2E8F5A2F36068E2090100D2023D602C557C3EAF2511C8A8F5F41A1EAF243201440209130\n"
+":4021C000FBF6C00F47AA0801E2D942E5338666D60A1DECA440407C1A181EBCA621CC1A5403D5DD34E42D03BEBB6F1F5E539C39094A020F0EED103FAAB9100383A89310BA58\n"
+":4022000097E100382A873F5E55981279068A00007E1A1C09E120089A41A7AEAC1DAD400D0E07D020A28B1687543A89D4BBC3E4BA0C04C61F4B6709151A3EBAAE5C23EA9784\n"
+":40224000F13C80AF1DF297AEABD098038AD89731711E82871010C61E40EF156D1618D0E2B38229734032EA05F1F20BFCF504E89805B788FF1101C930D385199F6E77A4685D\n"
+":4022800084FE334F129025014900FBA493D034824F1E8F88480D0F487AFE0040F33CF0048D6088961587903BA7208C033481D3441E8D2258D78E2194DDC2645E960D13104C\n"
+":4022C000E10EBC964820776153A05C0843DF8FBC079D1F08063D8DFE3AB22F2271882459821DC2B02088244D002068243D7943D87A47D87AB00846CC1881D92E63EB6F71FB\n"
+":4023000067BD568AE26002FA1FFC7B74754B4097AFCC112111077BDFD8F82A20D44010154E8794C54896F279B0F55EF89BDCB05C48D44FF40FBEB1DD11E42F4008E02643E4\n"
+":40234000E1593135C1E1BC02EA1861007D22C45D5B9860196C5004E2A83460754CE8803CD00CFCA62A3C16E080620C0EF298B082E6E022A609BF700501B887459F0D0F8F5F\n"
+":40238000083E3EE3C9115B0060DC4202686840652323E52E04D90302CB560819EBD6320D3CFBD48F8C0A913654CBE0110151AA75F9F5F4580300A074204FCFB064059FD080\n"
+":4023C000C43AF8C0A93C3BA038F36B4102CE68B2E918032AAC825E30271E6D7C2059A5167888C5824931981EF1812A0732817CC4D4099267770FE9346D260291B606438E21\n"
+":40240000E0A985F00140071080F4EC017438A896460047D80E6210622A33FC648C4478E9D8B31F3CBAC4318830D62DA21D0720BC781B2BF40612647209F098810008045EB8\n"
+":402440008254301CFF2E84B4385ABA3D211E874ECF280612D510895FE8EE24BA7670CAA1D9037040EC43E30380303C16EB6A41F3344970B9912980F1181E080D90ECD0299A\n"
+":402480007AC9FC7A1A14498010D2293D0C462522A9341E7554C174BD81803D04842231341EF0D4D1066210EC7AD2603EF431A8FA16F4FA5DA889103A4405800FA01990BC07\n"
+":4024C00019403000B8BDA882BE654120948A06CB8E2F6820C782024487929055C96FC803F431EA5D993A2480187B069DDCE036890A1A20BFA29F0BA4AD47C992E217059EFA\n"
+":4025000033DE2E8BCD2E5E1458E4002204FD150A3E863B26029984802EC48F26800E9EB41F206EA23F19C3C185E858112AA672A6E206F5E9210E240F4EBB95B80442E9C93C\n"
+":40254000B1F42D498573488FC01036357496390E6074388FC3B21DCF0E7428C0C1AA83203C959E8AA7294149846C471160E3A000EF0C008C978041A0300F01A754AC9E2AC5\n"
+":4025800020F01FC153613C0C3F432617280A407514FA7E0C40AF233908AC8021D594A5D2A0444F043480312445C700030034810F0A198B1502A00DEB69517DF42FFA7D68C8\n"
+":4025C0009E211026C80B3290FD454C82602F0C1827803A882F628694627E7F10164210383FF4363A3E344E1600B26AA1D1EB00910147EA884BA1F8C589C0BA1FD05962A137\n"
+":40260000826429C0CFE4FC522244F00B530548113FBD0C628D1A302C4AA2C8749C4154925450BA28F87D0DC827090C03DC360650CA5D0F01D8F42A1A60B54C1F6DC00FA145\n"
+":402640008BD03C4F234413B8143B43E47A47FC4D403C7D2D0652740913C0311789FD178C1494C5E4391D8201F910091BE98BD0D285E3E0C206474F43AF933D2EBC5E3E1216\n"
+":4026800020C79D371169D05C04060FD66311E0D80FFA75D0AE55004494EEA4613D89A147A9E187A64FC7D52A6206F4FBC164EC881F77A09800480C0EDCA2035757159625E9\n"
+":4026C000B11430C2085BE20FB2EFD991117AFAE4494EDD423F0AB991C40EF5B7E9741E80E0148077D0AB646074E5D08A3E6685203CBA073A832C78BE78965085DEF609890E\n"
+":402700005D139A41074FB51E3F10F44AF0FA24788AB26052340D504049200803A099BFC4414BEE22A1CAB360DC3FF06A0805DA90838354848E2C8C46A1992D2188982A3BA6\n"
+":40274000C1248DB22012EF4961E8BF71340C8180A81A03BBA803A24BC7A0B2C402007B6B1D1C79267F1D26A17FD1B0C43293072F427C881A6B9317799DE65171F29E5BF923\n"
+":4027800010F09011BA0088FABED87C68AE3DC9CE200FA31ACF866D91A059F8C7F8BD830480FFE213E48860D3D819EAF7FA38957D50602069A6557662E17A2B5CB87B308013\n"
+":4027C000BE8ACA21F86020C62E85021BB4C01F348A6C77F1DF5A6604FB0361020B9112974F909744EB990411754AB176A251C20E0FB8EC8C32F070D1FAAAEC899980425FB9\n"
+":40280000458211D050C1993E6912F333CBEAEFD1428E426622291F0E52A45C0597F9C9286810DC403840DA387DFA503DFA46971A431EFD241C9F62024960D3D7EEE880E7E6\n"
+":40284000C869D9A84A0B41A2A1A23BDD001D75CE5D44A022C06C207A2314BA7FA078BEF08EC0D78A2D878D3E2A1801AC7A9FE07A7E787881791488F4FFD91A235F103C1FED\n"
+":4028800014578B0462448302513CD06C796D09F2D831057C5AE25DF84A7D98723D46DE80040C7A0DA47B9CAC49001FC1FF0268EBE02440E1F444168000A09BD379C56898C2\n"
+":4028C000F4257977C8D933E84C21F149B8CDC058821D8884414749F20D421FA2C8C41323B067861E40CE5A9003B6F844043404DF33A38887CDB1C6900089D3FC650E2C77A5\n"
+":402900000CF178B848402ECF8D225822EE1D31178D011BCAB7C223114301D00D77F9A0905EC11F13079480491E3C9E05B1C44B1C63788D81F022006717C7AF3EDF0800598D\n"
+":4029400016CC73B951B68801F1C43D02A5B086308F0690725C182553182E4096103BA560412E14C65DCD022210FE28709AA12109610F850894C00150058C8E3B99D0484E2E\n"
+":402980005FF6414790EA0B8E9888F1CF188C0F00834501FCFDE419E20BF80B504021CCC0E82CD2EEB0F1137B210844003F08007B3360823430198F631E97794321E57AC23F\n"
+":4029C000F2BD816C43C2C03E77740731600610819F34A917A3400FD19E890988FA33D8DAF47C31E6DD17A58688306400F004723C45B90B8D90F467C2C1A039221232502515\n"
+":402A0000E23E44522F1ECC2400979C45347A13704D039AAAC0D539BA10EC404A1A360547D4EAE6587114D32D0B043AAE64EC92A79FD2C7869F952D11438E2FA1C456CB887D\n"
+":402A4000AA97A35F8C623C0031D41A340D3F46C0168F92B9F018F4A044841DCE1C7C2D706C5221A0B20B999D75823E25932CB5616004EBF921A733CB2487C30AC3E14F4175\n"
+":402A8000BAC802B05B88BEAB0E182744B2A9E104386A80CC9072800081A25FFA15610C36421581C4F46996BC76D86DD23D920C910A1182BE8EF339905DB927E948DE59F49F\n"
+":402AC0006431C85200D330187A3C1D4F464325D6B2E40AF1C1B5C3001EA0D13008540D025B976CA3DF94E3D0A1C5D56043C4A850F0B750D8C8420EE7B03EE8F52E964D12F5\n"
+":402B0000582287201B4C472CF3AB42E32323C4BF871C105D921C446CAA34624B9EA211B4DFA20EC804104B60809608610C214022E22CC208FB024470E18747CB0F55E1089C\n"
+":402B4000005B047D6BCE80796A7109C010347A0D3D1B9E58D043A7FDCA6203291CB902E26202007852F0809BC00FB90EC7BEC584DE00B851309BDD96F27D96EC3E121A2A7B\n"
+":402B8000643D9D2426377F998FA365C8721ABA6CA0BD1B963DA9B83C4F34403E8C7326060F46BF23E840B1A9C2E265C555EB1A22CFA35F99E264E8F13253E265E339A01CE9\n"
+":402BC0002B77D890FA35F90F4463978B2986853CA40720016419780D04A85886C97843CC83F723994C36721A3AE258A8F12C42E25A853A201BAB7B0824407EBD16320100A8\n"
+":402C00007CF604E682E944F1053A275040EF355391CDE10741F5D70888D185E434E101AC9646803FE30731EFF3D1BDC8444F15F89793B60BD0B1022555C19F1D13E25D57B0\n"
+":402C40005A5D1C225E59CC1083881F22251B1D67402780919CE865223D1F1859C905E279A3F49D3110CE203069E8D16795ECC8BD3B47AD8707C393A3E906B63CB8BA7D6734\n"
+":402C8000B83D2E067C2E908B83C007A2E5DBA4A54180B9090B9CCE21F0C8E1545978B1608D13CC91083B7A189A110C2EC61F1E1A1A5D2E5620355091B15D6578815518FA71\n"
+":402CC00071750C86E3036F4A50083790F36D22A60968397A3760EA041803F00A8B415266EB02A4901AFA84E44C22407F6C0B5205CD7F47691805E7B631EDCD231E85DF4610\n"
+":402D0000EF23D0ACC3DBC408FA3779D024660D132ED46C9720165888960E7D10CE4C182BBCBE707BBDC8420BF58C12C9BE1EF2162EB0FB1B188F4C218D8C078CDC157689B3\n"
+":402D4000CDE8DE24C8B0410A0020C027A194BF20348FA371C7C452E25721E89612327C56C09B010F61700E5A01031C417068B0992481261260E21C164386540E42440EE9FD\n"
+":402D8000FB52F10760F76AB884DE2B4122DFD1B9281A84CD1000B547D1B90A1A6AF81D45C4C7F3E8F91E0058D459770510D6684E41DE8663CB67C8031250B9380C0028ED58\n"
+":402DC00020C72E8FC39000D7228870D80E0D81C283D1B42409714E6104BBFBA07D40208E55215914063044E4F46D1BDE750F11F0980286E2C8284303680EA31F0D99401510\n"
+":402E00003C090EA5633073358841D3C090AAB20AC1043AC6204DB028BB200931A407E24963976E53D800637611723C0800347D1D0183C083EAE3413C4F0B09881B62B1EC01\n"
+":402E40004681EB63C1F09C198EA68F86BB0AD062271C0447501B11A630840039003F1A430F18C72A00055F298A1BCF02C703E7E3D20A3D2FC45E1B0348F40801716AE8100F\n"
+":402E8000821048E903BB635C4403642103C620D3CBDBA23E82BD55EE2407894844093C00D09614C0F12A3040950918B156B01D5A9207E054D1133A2A188662E343003D4F4D\n"
+":402EC0008E274108876A568F80AD878CAB8C1878EF30817EE8DA1E4162267023E8D8D4886A9F16817383D959E40608D4FC8D10FF1AF218FC0785BA23E95B858FD14387FDE2\n"
+":402F00002007074100C1D82BE21BF1BBE100493EF0B4124C43E22C63DCFCC2690684985259041D9E782011275BD0301A4129242079AA15306BC76382201D44C78C5B10F166\n"
+":402F4000C3A8857E48D82F3544238FA6016209901723407BFA584D309C700A09343B0A947484F21A21E89003E176B3D0A6E2101A00E5D463E4F3013401EF09BF087FE2BEA4\n"
+":402F800044FA3DA11D03E1742911600C4301021E0F322E274840B08181210EEFD43DDCF04DF006080EE433F510F47A125DD6D0650603210211D5A4D00FE8656487447BB60C\n"
+":402FC00048EE54263A2DD0BA48B4408F432910142BF43BF10101DA06AF88EA91E99A53600BD3DA982902B841E38AF109898EDD0311E430E52DC46D7ABFC878DEC880645D26\n"
+":403000008C403D1E4021A45A2E83DEB44D130BC8AEA455F0A6D3F632C094A88182F069DBA62A87FE2C4611D8A8F3D03903626063C43087D18108F48C488EA14305D73DACD9\n"
+":403040003F37E7184645F38D81E71942127920FC41BEEDFE9908068607A305D71A8D12E900A881F47800F11E1102801300D02E38EA9892D872C7D1828BB5E8C1321C1003E5\n"
+":403080008172C500C9DC0792B7984F17A710881C280720AEFC02E15E022197C308363863C1004C749101DC08753A388804AF67E508127F588CAFC92ED8F729088E88F1DE0D\n"
+":4030C00071608603BD18167E2EAA1C34F1E8C0B3D32DC90C0837E8C103267D181C88E0A43A32251438301D19120CFBC20C580557DFA7B3CB85C82A51BEDC181C90F17E304F\n"
+":40310000B0C5211E82DD11E3C0BF42098EDD3BB662116BE8C0F481436BA4234C090AA9597A32F8895F4607240C2603280903A38C5046F422F454E8CC220485D6AD21C0DA6B\n"
+":40314000BD14BD182E80120D4491AE31F138D1103D181C89950A6D814902EBF45EE18A887A30411020E69517A2FB058BB5C02AE89E32F45F68FA4E20DC00832A723F6354D7\n"
+":40318000084A404F6597EC2415053E92451AD62F461520040DD1455BE1D4A9C5D682E39FAA42F449764B1A10A552C3E8FD92F0183901FE8BDE2CFFF29518423383F291E7C0\n"
+":4031C0004E82C53F3CFFA308A527E8BF84814E926C2626D1C2FE35F00034710E04179C480BD186E468053D4C68207CA48DAF43350FA4EF88D00900805AED8320BB14ECB12C\n"
+":40320000528891D26F65D41822240F2780FF522016E62821C3C08441F157498587B198117692AA3D915E46CF35342C580563D816E4A882240203BA349F02C75873949920C5\n"
+":403240003C3FEC5BF10631132DE6F9847D1938D5C1023E8E188A88DF0038A39904BC837D00A80F1C81C1811C8C72A7214C80F6103D1886A04897A0D2C72D7440F13A4480A5\n"
+":403280000DD3C4627B09FE8C42582454C3DD0058F80EB40191210AA6044802C688A43D1884A305D0162A289B07FE77C08266B091D5DF020CFA3104BD188A5D0A964D18F92F\n"
+":4032C0007983E8C433BA882042C0E1E8C43201908E2E45407E8C43206886301406C636E00257B56D0BD1886572B877A098F222F1F4621A1D33942CDC86039945D5A0830A96\n"
+":4033000004111E3F8F428753CC1044D0D26D17DDF5AE4720F2681742112A707AA8B489528703BC78F5B047AC6DE23E74E4408FDE8C4144822DBD18926E04021200219222CA\n"
+":403340000B484022BA491848C2D7A4518404137D18965E71F11EB66B1EE5D21113882C88ABE932B2B48979DBBC4841C0C2F461FA85A888A9E30C6160944848604081380201\n"
+":4033800000207301C8F0CD42B70424EB9602870364FF340282C02182034429ECA5B160A08422A4D70A4180A2F7A10A0A70206D01CA7E64B020A880538160C05912212F12F9\n"
+":4033C000D02600CEC06E160D1E1ED020D1005381A0C0690C210A20F778970B01C23A5DB1078E0134180F02095001F9FFA5E403F1108081A81CE80C31EF2731E811B3C01626\n"
+":40340000216828C74BB38FA83D51D0D38923C5818C74F56B5A013F73E889EE32FAB6484C23C4E501C250CFCDB788808462168E0BCA874F1437B40019E9F9A3007C24F020BE\n"
+":403440000F14D81007AD99840108D1C54F1E99303E856829581AA7C014150421012A60615D1EB156220FD01CC4790065A980031DA19981D2AEC8420730F11E80991DAAF04F\n"
+":403480008D53BCF736EDDE0691DE10EAF604B5F41700C591A60A79D5E44432C8623DCD6E705C81FE5F758008C48976434791C670468994966CF89F6C840810A040065959A8\n"
+":4034C000A43D58EC3E0C9C108FCEB3A26E92087897310BDBC0D136C91EE74E2ED7BE1340D9F3A7C100C34D02400D3991354D3087CDE7846A7833B8FD345626B1A63C7ACAB9\n"
+":4035000098410EB0F71340D136FCB65E3060540C10404475443084207F9BCD520286B087C38BC3E6F2F48BD30C0D1541240A60815E6C2A104C4D40B44D0780781DF37982E9\n"
+":403540001E6F2F53DA7765E6EC12F39710801E6EC25403F3798B9D0DD225B4F60780B873F44D490C5CA67C7CFD9473CA3E6F311EF29F1602D1049242480C0226A95B188724\n"
+":403580009BCC8986014134A6F682291BFE6F2A4A1C0EB010B9266681287A25CCC1F34C9824C602ECE408E7E1F377F091E530406993C419405E9D4129A2491C3E6CFA1F37B6\n"
+":4035C000941F938445903CD3264BD891240A18D1A22005F9BCA4A303A6828706E00A4087876404B32810008B3382931908B1E6F2819D848B718503448A224603408AA4A03C\n"
+":40360000021B367402A7D88E458E3E18E2B08243111220218E9220D3218832F8D2218A228093134F0ED54D2144D3210832FCD220A20C09489134C813487F20CBE596021740\n"
+":40364000471A08F6488548016C07A851F12C8CB0489A23C92287A01AC478ED15510240107C90EF778134471244572C040EAD0E1ED6323619F37DC0F0DFB1F3B9808E2246A3\n"
+":4036800084B64061E8309408C3EA1831E88C1108850C0471104680D2020C34400A8480BB0410CE0687C109C0469800208B141D3F5C22E100129A031F94D41202CA20CFBFEC\n"
+":4036C0005C14F105D8B0569AA2E74EE18805E7EE447C0770242981E7EE552E5E0F3F720B06B099E6C771150D713CA50009F0249FF3AFD10245E8104F80E3AE0733F5D39803\n"
+":4037000085512209F177B1F07B19CC6393B0802E0A79CAFCC0135B54AD2607A5A70B2C150E3642208F904E4BC62EC20AF4E2A8B26500A264795F982415DCA43879D07C5956\n"
+":40374000ED5A728B130029003B92B07D2D6A3D5562900A257553589A83875990902FE0B6330BC0B37A9900E2751A218FA727040C1C4DA082FF781000B328333839CE28DE5B\n"
+":40378000363D0F785DE74E314028812134DC5D5C9A51A1E8FB72F520D21E84C220D0BED24A1321A63841077097241133D2538403613847C52FC5E9D82323110D30AF24222B\n"
+":4037C00033D76F841A8D88F9BF78C994BA43A082CC9A443C19D85DC5185EB3624BCFC0C64C243527C146844A35DEAC857C70EAC42FD17946180103F039A1E83E985B1F640D\n"
+":403800001808101F039A1C72E892F4809094CA0544CEC974114B96E70D8400ECC03423066E5217F30C907A878044EECE1A203443F6A5A8E80C5102C1D08C63E431E407F5D4\n"
+":4038400041B4B2118AC14786528FA3884AC880040253015DDE1143DEBD46C9A26C1702416FE025B1F03E38F8A160804F5750A2051AE6993E0313C1375644889A3E95DC6A84\n"
+":40388000047A7A30803EA6E71CB441F2B938945955E45B00D6080278278E79201C9F0238C830F82544813F04171588080B107C5810544900281D090E342918DFCA344842D8\n"
+":4038C000251EDF5A1F20E3881607E09A0CE31108A892198A231405C891D23B45644027828E69342205A08677480552B2680144F0531C90CA1EE78B8BA813E01574033CBE10\n"
+":40390000848920CFA78615E9B991626F8C1345D860024842082A42D97A093F3ADEA842807E75BC709E083C4FC420B79D6ED2038C2A2E4C034884BE0566407EA525A23218A5\n"
+":4039400080EB140406E7006816EDD3A1ED68710233FFCA248770210F4A490B00528094BD17009859BD443B905873C3A56484A2C8472EBD482C3A2411F81D70BAACF47BD987\n"
+":40398000587B027072F584EA0CF40083E7E3E434850385900C1024DA89203866AB606353022C7A3BDC583193E2784573B09C879623C0EF949103C85B2A814C1479E7584053\n"
+":4039C000B63CEA847DF7403C74044D61750268D11778F83092D293EFC5F108EF2E1D7EE8821E102913FBCD3084481C0805E040CD6BB13A7403446A8A7E5C2610480C034232\n"
+":403A00004190B5438EF789887802981F6015E4A9E419484581E50EC6812CA4A289446A9514940D711C24030A41038B0621E20CD93801D195BC0944380E58319000CF102437\n"
+":403A4000C84069571E301E7B9A5C89287B41E87A85C0C39EA1D643A7E388BAF3AB688206C100401E45679D5AD30FAB08886E86501F1D921F7FBD1DF182C791FD463C81E5FF\n"
+":403A80000B9C2042F3AB629E756A2087D745E879D7044033E8091401D1ADA32C208A50FB403C6268037C91DC8EAE8E091605121BAE78C98F13AC967011745328865D6124CE\n"
+":403AC00024890D484022298003C4F6218020284500411A06038845E063B1093D05D4A02DA9622271A27352CC5AA1A43D319061A63A04B02809B8CF4B8B171A8C1087A8913F\n"
+":403B000084D1CACB2EE5DD1F12E289A27BF2800435CD03AB921E9C20101C8108F939A162AB13C8813839398A4689E048A04AE6919794614723087A867C726FC4EC22314540\n"
+":403B4000976F0B0F280D260F26084F051B918220901A18110D405E4EE08069E1AC12EA2FA1F00330FA3A747940C9776C7A1E76DD2F3AE289B86B1BFDF3D422A02C150222E5\n"
+":403B8000B858200404782C1402229F73B009220B05808F99B5058234783CFB82904D81E0B3831143AFF20BB722C7CC356238E25B102C76B351300412C0BF5C86093D58259F\n"
+":403BC0008CFCB8C078DA4C7AD528C5690238B94581F93E55AE321102C728640DEE4994897C481EC2BFA062C481C50A4C0452A2EFB9A1EB05B1EBDAB304A2087EF13118E031\n"
+":403C00001B81F8D309815054D13C390390816174C25D79325DFAC66774A8C1253028DE660219AC052F2F2A1130105BA12028F2501EBAF774B15D1014575B810D24F1C4110A\n"
+":403C40003C9F724688216DF480A2293EACD519C867F0701E93D29F89833A00C05FFB579CBA3DB87D347E5A4D21080C2ED711299C484ED71340D622AB2848AF18DF173F7CA0\n"
+":403C800013A789FC8880340539D9A79CFC253743DC0F3FC22EACF34C8AB9A4AC7E23190C110D604F1BCE48A6EA83C11CEE5147AB2E07A74C06C981E138B43A8448EE7D0E53\n"
+":403CC000ED7050BA0CFC1E38400753AB0981E631F11088129880F6DAE092627FA5A64406DD97C7C47CC43114263102638FA7284C071206714233F546F1102340FA628460E0\n"
+":403D000071004194224762769102248F652FAD3E47C49A83EB53B3194D31589105306681027666BA0980588E984CC8D31507811491157A4B387DA2442588EB23234C508942\n"
+":403D4000115948765F497E8F2EB63A76140C02703A80030211425610001CFE44095A3F1CA1281C4819A508DBE6F4931BA7E444E5013C7D195669FAD5E50294D5104A1ED9A0\n"
+":403D80001E9C2463E6F212F26699306A87C3D00A8003128942A01D280265E6F493D0EC8909C6A0C6A000E140A22004320412284D2F37FC880BE6FBF2204D3F37E0153D0273\n"
+":403DC0004CCEF37FF9E0408050A13CFCDFC83D389870E20A9425A2371D81422A9A413449124200FD99983E3101107B270C40D254A0034D104C9FEFE5B3000932B0B3033C0C\n"
+":403E0000DF5644981A9D210E542220712DE6FF42200B333680A001888802CBF040A176B6925E4B404C34472F08C2E47A5490BD1FBC9FA6B688C4B8804204701B1304D42031\n"
+":403E40008C9E8FEA632720C60200A2CD50101FCB81626BD2D4CD8571E0C541B2509F10E2271425CD7899743C2157404899A0C8D1DA37632022947803CD6160D51648D3B07B\n"
+":403E80008E300270089323FCE496754600B95A665401302BA7100680A449F518E882A0C820675D72459831E436230747F117D02984690992243D27A83E40F71EAD4D2284D6\n"
+":403EC0001DEFBF922B45834846AE52F133C1F773F09204715A2CD5B1D8900412045F20EC226508FE98FC229A61F1A41F10450450552899A510C0990430D81C7B18C44A2FEE\n"
+":403F00005B721F48D1086F576049008591495DC46A86A98F03292432FAB87E620315F814B2223543189119948A66016A8676453AE20468245421D026869264222C8A866C8A\n"
+":403F40001C0597713995D580110F032F9ACA047D228342ECC0087C81953E7061401ED3E051A219940550E9E346C106B8D86174AC28F477F1EB0D858222E211830B1840F420\n"
+":403F80006072B81105CE1E570435F0054041E263330579C514841D0A08584302B80484488EF382E2A1E321A86918252243C78775951C91CEC02033D48BC708210A3E19DC19\n"
+":403FC0001F43101E14C20D42CF3816365B247A3D3A01CC7370118501605E1986C1E9E10142188A238922609E2A9E02E8BE30C418C6338D8388EC3D90042914471264B133C1\n"
+":40400000E702D92A4AE2D4B9300C73800018C5B3C0CC1EC423C0CA1E86C1CC2F3C0C61C0680205A0CFCE04E415A85F0605F381ECA10E05B381E0A2068DC0DE71B8B00AA6F9\n"
+":404040000692C0DE6AD8B0078F6221E0520F6229E0510F6239E0507483A09867813C3D8E51024D7486B97147B1258EA1FCF001FCE04487A18007072811DA3EA12307B1600A\n"
+":40408000F02287B168F02207B164F021873143B117C8F020AC5455A44780FD125DAAA24780F10A8996780E8A4651E03732330F01A9919A8191918A785D760C047E7023215A\n"
+":4040C00072251338F0159A20CF0153234460C050F3C6708E27809C069CD4743CE040406935086D01C0903670280C640242E47885F05815C80442B36441D0D30D3F0294088E\n"
+":404100002281EE1EF427894268851E7019400F27B10E4304DA9E059187024FCE032E9E88022D80666069C40E714CA1607B98100301AAAA2F6759944074EEFA22B866A06A7D\n"
+":4041400081A0786C0E041E7029480F1EB384C44F3C45FF56B420198806A80E079641094042F71F2C867AE3E3EBBCC1F6E611C2106A7271CF631810D1C78FAC2A045F2A0AD8\n"
+":404180000820CC3D38538240053C433D6FF0FA91FC709080BA7492DE37B5100CBB397A82C4BD23FC4690B58DCA0011788214B0948104289402EF8781CC02F0EB58F285012C\n"
+":4041C0002803DE9E18114C90C690029FAA9F045347C6C0C627920131A027C4089EA3440422484D0286609518D882EB6860602B50304A41FCE0F05DD21A667111C81F590AAC\n"
+":404200000F67A793023100501800076F0C978D54858605D0CFC17987D692E87B2A38440F38D935628006C0C0C3A34F8BB2DEC4C1287072C770BB08D20083E6A86C42F9FBBD\n"
+":404240005900D40E0181CC1B003473AA81103D6AB43C4E3841304379F1103030D0DC9E33109EC25E5A1781100338B2002601ACB1872EC65E11003440D00A64C54C40D00A88\n"
+":4042800025820114025CD6801A594D406804BDD2B2897E19F4F562410E6F208408699D84D1083C907A3D5F786071FDED31D100C0C3D8251034D38972EE62E3A445C74A8B48\n"
+":4042C00079E9AE870A20E09B441D2118F5D6C17B52110BC18418675E845D1C472036D01C41C5C3021C655508091041223ACF42084F047AD210EF1E101346443B48617AFF8D\n"
+":4043000020ABD8471E529A7656834CD51C3D4496404F8FF0C40D0A81E2021880A150003080400433F56B11C181AC349AA34F82EFC71D8894C7001A7F03C3031E1BF83C3A88\n"
+":40434000616231F1B7A10C7C8DBCC63F6FE91F316610CFBF1F10183D4730A8BC89AA2F285E61EA59F3257D4CC880A2688B6B2680B1E775010F404140D615FC668A3D088A40\n"
+":404380002055C4025C008688A9E49971F3BB6A6050B5147E6DB51F3BB7200509510626A3E521329C444D4FD46A4B7A8E6CA0D31213257D4768806268876B5C7C3C8426029B\n"
+":4043C000040426020B4F51CA3CBEDBCF00E540110EA0D50E558386C1BB60D9B06BEA3AE443453008610CFBB3A13147A07790F51C3184DEBD5A47D49B45EA3A46BA4C18BCE2\n"
+":404400006F44969088BC9B4065A221A7A97715F51D335DC3104FEBEFDFB9CE701F30F798103604420F24D847DA9E6364E00244260C0F6CE20981E39BF2344E3CA6043D8439\n"
+":40444000822020518F4E01C346DE620589C0E63491344DFAF91F56290F325A137CD03802116403F14728C40764A6081A691BD0A3E826118828326240239891B07B89BFB9E2\n"
+":40448000451140229A66F30121A46F602C082234E483180518813101A7D0902470146504CC4021872726180180242C0C1339B06F42900076D5F014027F8BAE8B19981A2613\n"
+":4044C000E753D1091689E3A7F7217833F072489A66C7B021058EB6C44C2CEBE7A238484F077A88447904C6CF870B47C04D63E8A6131E824F4A7091AA689E4051A46891420F\n"
+":404500000797AFC714480085731E71161200A540D233709700F222053E625820D8D132660002465C4CB06C81057790CAE4B9203A9A6866A031B958991D202CD04C0484723D\n"
+":4045400006917E7480DDDA943E797F16020354C00545504081F014A9C5260A93408802048420183D101E36B01037ADCEC48EF311E15D2507680DD6E825E623A296095C4255\n"
+":40458000881E25BF44021E826344B0244C0F3FD6A052F5FA008026F79DE204620383904875EA85A303FCEF12979889D4364C09D4180066726CB9268B9216189BA68130876E\n"
+":4045C000B38A08780939045C94219F6E6C113C115F30048111C72FCFB86388D01EC80F157B89A04A033E7ED42007C5C40801E03067D94AC812085C44639796014AA6805BB7\n"
+":40460000394013448C247520C240089E51DB1D06E910469912711086B913CDDAC41208BB89C8810363A6E566D2A1E83DD121898083C71AA90F0071A24213210200A01A084C\n"
+":40464000823E5F8B19004788FE879D1F84D9040792E8AB080AF080782E39812169BB04B81E42E35C702E0A005FB7E324B6F434F0F303423888808BB1CAC80B05FC08B62194\n"
+":404680000F899252104832F8F2030D01C0DBF5BD6094604725EE118F8E920824680DC5082758E0680DBE90631F55339773CD0F5D4B8819D265220C719B412A81B280B8012D\n"
+":4046C00034C9087B86504A2E55CE6054C08639E02E0CEE382A6029B431F885344322881305C5B25F1ED9085D1946240972621C280D07E97E621706274A02913C81CE00F8B1\n"
+":404700001CB86E8E013C9A1010303B617087ADA434420238720BCE621026E503027A7A67B440230608003038BA137B620C42C1C888D3218883E348C21C44EF063090E2212C\n"
+":404740000FC6817C080F4280F462946248F2181AC22146157999ACA8421932E38CE447F0B89EEC6BC1860EBB551871D48DC859DBE1E4780ED716200E1E990C08654F1779AE\n"
+":40478000EC1756CB10AB70808844823D5B3441C0708F86608838F70790ED8A641C67FE0824084106EE343D8A8032C1B8F044AEED38294086F950821BE444082C0833D73F68\n"
+":4047C000041ECB0BB1850BAF9711EE56A2F349F10963E084036BEB8AF7C1F2FEC27BEB8D75BF017988C92EB7F82E9BAE2EAB88207344D48F76B619708EFB3E41BDCC021BB5\n"
+":40480000F855C0783B60B0C52410DCB6F2FF810FE7D8FFD86E430440CF73B4220373FA81028F206FDBADE45903684300D05E7711889C5106510368762AA8F82E107CCDCCF5\n"
+":4048400045B0605B796730C042E433F65F2282959690340C03746F2401AD0FE880BE5CDC2F2E048821D743C5C9CF0B960E1130859A08D62E4960007A0B2207248C48E10377\n"
+":40488000D74B2830C72C222BF2489B180963847B033CC0FC878BBBC59F5C0D0F98798BC5EFE260F6F00091E529C85280E3D0CBDBB04452F981FC7A39E46FD80E627C2C0086\n"
+":4048C00024E8186B9490A0C07C0D941C9B888B8140B8197268040F354A02943C27FD110E3E6AC52026930B35EE16BB027C0B25BCD59C60499D1288244F8192244BE5204071\n"
+":404900009F0359154BF29F88F54E60847E703E18E1003CA2B021EB030970667AE4A88B8F313A16308021CA50FAD561E7EF311D7C92D4419F8F0F8883F6730172DF2103BB56\n"
+":404940004B14886EB2231E64705C90584993D8010342A0CFC194C4021DA4782C068206015DE31A528300349E439A31881E893DE7D81127BBF3E06603F3A28895C065AB076D\n"
+":40498000C06EA24C82F5B904C831DDD4821F045E8CF421B315A04D2560E83486BEC0774ADE004D31D35B05E35122ADB02E4C163C7A9225C80A5D54C004A688C6698C7E5EF3\n"
+":4049C000643B6288FA1397AC7B80ACB9B9288BF8D18893188BD02BCD6408887EBE001297A3988445F358A206C0DFE541F2008E90CFA35B101883343ABEF48090682218389C\n"
+":404A0000D494FA560C71C187648188967B002060B54A10D2340827E5202334D0278D7EC7651CC90221F31B4C0819AA8CB950509206B0904375AAC8866107966BC886064096\n"
+":404A4000A3FA14BC2E182309EC876F5B0818438032730D948952180C028DA9089559E6220D014694298045A81A43D660C90C0E52241006814592BD3EA42C0360515494D4A9\n"
+":404A800007C76F9A081D60B0277CD0B85E68D81604340DB61D6C2425A8DE0401566C2020CA46400341B84E81C079F40DE60688105D59D112047E34CB50C07E9D40D1F40589\n"
+":404AC00041F84CF8695983E007A6A84801E9F5D1303926A4923D215C60465808880508040092A19F22723F30CC2590D05A64C1F31F518963C6C2942763399085D3E8C5E65B\n"
+":404B0000AF65BB1528837C70C2078208ED3374C0A880DFCB2C880903A68034CFB348FBC2FB04D0404D68DF04D03E8982A8983B32FB84402408D344F8ED03B1390BD108A11A\n"
+":404B40002809B284662F8982AF562031631489424D144C7B707C4653F629589030C9A28C983B62D96183110290983B9D14883149A294983BDD14A83189A2990783A2990341\n"
+":404B80003A0474022310F5D63162C71F309EB68E3ECEE292E6A188D033FD22005B03219FBA38113FBCC5F85CE884881EE1301EBADF4BA70BD00884600C422E3CB42E3E6007\n"
+":404BC000B21BD380C3F306098F897970F0982ED6BC958C801E69064A860958389B43917439935DA8864117A796C8404744A862223ED293260480C50F082A895DE12CE20238\n"
+":404C00006C2426D031E01A623A018CAFC163A5E18B2C387C97F83A5A92E940A1105AEBE6D1D4161725762D4279729522EBEC11E9E0F1C57E1A1EF1304091BA621F5D631183\n"
+":404C40009439155E428F2F72689B0D5FEA053048D00887928B858F25190823E4B002F6EEB088C1881EC08418F7E0A1792BEC7B1978C2F0348AB1B8F92BE91EDCE943991570\n"
+":404C80008F6F1220250EA78E3DC407B1EC0F074131887BF255C0CB001313031004E9219814A0C754745E4ABA20087B4361E710740418BC523E20D8094700488E1220131346\n"
+":404CC000A424098A1063E2CA812F7CB8BC3E4ACC64655B08BC952667100FE4A9243C94EC6022980C5D864CB1338785130460E96F02EE92043CC2FCF2EDE10629B7D2E78637\n"
+":404D00003881E5F607E1140980F0D013498E9EC91F306416C4943AAB311C881BA846E460128A2994672299C27343CC19E45C9493411A42263038346F799268012C401268BA\n"
+":404D4000022C7BACB4750A222096201934001620245080A9744030B25880E7F865890C317618EE8636F00F28D88781009BE8B1530A7CB64638F5404DEC41C2860F2011174D\n"
+":404D80009887C436F58EB8F4FD191806986B234BCBB905C80A461C722B458F5DAE1303294402785330A4290F1E2557402B961452607C8C407E4E24D01A21594C0D504BCBB5\n"
+":404DC000C3E81AC10660D08A3E3505107CB60580B1D822303BE04CBA6F644442E0E4E85F02C01C272602E12819D41D0F98320729C90C1800C8081264BE21D42C4644338036\n"
+":404E000010460D9DA2844B8A88E84444C0582071D48F98300FCBD808798330FCBD84CDFE03D8A34563A03CB940BC9B5D2FAA85E1C271003E03BF2CE1D127F1BD06B2E90F39\n"
+":404E40002F4F89825D03DE781F160D53A3B35B4483214263AC0405429040833AC832E4A18D22E4D01E445F2FFA9842040BE0103C6B9C04B82B88643C22EA225065D2471396\n"
+":404E8000E5EC110409E04FCB8645D06D05E07081F2C7B08165759D43CB85A61D12E0A689BC40A08BDA17C407F9D17489704E2000E3E947CB152262F867CA7DB9CC3E150EC8\n"
+":404EC0001F2F6D180832865ECE425793E3081B548858948F601FCBD9E9836061FC111804EF8DFAC8CF0874B523E9A962BB807CF3063D2C025B17C8D4AC8185750E02F4C97F\n"
+":404F00002E0CA2E101F405959FB6200F00CC065D752CC9825463A30D6620F5D452078281F83D0631089F03C863E9EA228744F4EBA522893107AE9558BFF8436B9350EDB08C\n"
+":404F400002F2F22A65F24527979051259449238187729D1585E0931E0E7BF3889210903007911FCC46443DF8BC7847BF302089A046F97FA0479374632ECC6B22060AB0F3DB\n"
+":404F8000036898DD63D645EE0AA1BEB00A5EC737163B22CC42037FB82748D11F7564E22C794FA0890EBC083BAF00D31FEEBD22E427BAD8893308B80A02E008101589330FBC\n"
+":404FC00094DE09030A2C5DFC01385E12982339BE3F8744D84BDA9C42090C22CF5AA18821EB5072098088C035872F5F97113C0881639065E5E4411C86A44E26588205AE6B71\n"
+":40500000B62018D01D04CC04660177D4ED2447E1E501FC65294E635C6623CE0CE102D5CE099C3D80A528CE0B046081060B042081016A22F2CAC21E56201F2F17094B9A24B7\n"
+":405040003DDD3638B2A09F29791D48F8B5AC472240D32ECCBF2CC411200A798D2058B038CCE181E805335C54F2F1597363F133BCBC52645A8114C0C32ED1D25A026997CCC4\n"
+":4050800017C898A52F977F47CBBF6D1A62314A08F591C8F3CC59044744055097CBBF488261100229937DCBE427B1897408128691E802FB43684083C036EBA7B20288A0CB3A\n"
+":4050C000CDC5C5ED0763E591039AC431061D69BA8823D692A3AD241C08E03146174705089DECD0E2D8C70C70D19091C03F014234681B23FF41908FB44A866643324043287A\n"
+":4051000052D89A442A0282A6FA3A9887E33CBE02079317CAB0656741054F000CA5154D10709900C9910BCBC369780B64582E8CDA931619F4529882DE5E161150903112153D\n"
+":405140004A33009041A1A3661ED9302F304425AC9220D34C408F2BE04814211AF2F4923E56162CCAC2EC27E2D07817972892EB1AA1F2F1D0F89C884010289F20BDAABA40CE\n"
+":405180007EBC5C48326EE540B8140431F85529BCBC6C26993B3C87978D0A42379643182DC8D6CB5110241F00C5E34758BA24B7978D040E2481B0815009CAC7106B5BD23EAA\n"
+":4051C0005E353F2F1A25E5E31500F2981B0815496684B3029418F03AB8B0051DD703911DE5E3244A5064964B07F845144812DE5E3344A540144F8D28C48E60B84828600495\n"
+":40520000F8CCAC496702950E7D5032A0299323BCBC62894A0E12CA052A09603ABCC234FCBC6465C9305C9331E3E5E34506555F2B8A08C6D94AA003952196711236E243B3A6\n"
+":40524000CB444428580189D088C0D2031064401A02CF7AF1A181D0CC1B5C15ADC0F2078E82726D8CD8D100F0FC081DE859B100C9D01754A230800293A876FF1899C118C1B0\n"
+":405280000A5AA5A2842B9580B5F4B8D08F00EC8C0F0084E9274E8074172425A645A40EB2070790F39AD6892D2C2258022742543D465832D306D4270160030207AF08DD08AD\n"
+":4052C0008A1972D981F745D9738AE1F5AB5A0037AAB206E391F5565941C04794FC20715D22002876090803442D244093A004244AB3C3604C1F02D719F8040EFE43DC4719D3\n"
+":40530000B0121E7A2F2F30958ED47E3C97B9424B9AF48F6E8F0807E606D222C604BB2A7A460360D6073C872A443790F58BA5DF8BBA6406183D2346654FA7364401F6DD41EC\n"
+":40534000768E38DC2207EF6DF510FE029B40EF22811394790F6B9C3CD38877D305528103468BCBEE85E5F6F2F2EF829E577848084337E910899E6B5C7B51709A22111208AC\n"
+":405380000D2C74F510DB9808A226D341810004220402227C293434B84A02E461E651C89EE68872408AE156A470BB90AC40C0581BCD4C13C4F4E52C85220F409F965CD891DE\n"
+":4053C000A4198BD475421390073F281C1017C621E246DCBC1CF6B645E20426E4A4A2128F22201A719202080A74865E1D6C21D83240DF000FF38BB85F04E93C01709BB802CA\n"
+":405400008AA0A0020B4050503EEEBE016070144ED22C8EF184A1003E9A5E2343B00BE6B3E0D91247708BABA724188C1EA564123830038269EC3629F10880522432F6DD12FF\n"
+":405440003896603274304A6D6B11741E90806688185C182089F1DB04A6489AA81E1B04588042D000011AA811A281C4410042700005F759114300147E900494705460F4736D\n"
+":4054800051E01410F190588020417F63260F27DF230860163CC24A5AE4E202C1EA785DEB663EAF07540E3FB90E40F53A28FB26F84EFD8CA0BD939C5729887446831CD654EA\n"
+":4054C000824130F630FBA8C87DC2DD2087A54704E9018D1EF7151EE3E93EC4D5108005E7A4080704C74C308985EAF152F07DF0823E13E12E93089D00E99A241102009D0490\n"
+":40550000278F8DCBC33A620104A469E0010CA6E81B75F0065E19502ED1D021E4C005C7B1D816C1863DC9186388C5D6E225CB8087579A210F7E22097285D825DAAD822877FB\n"
+":40554000C5D8922690E44106E410B3E025A1177509E5A41411B8810E478909ECDF64050240DE8894E20BBB63CBCA20667F4517398B13E22C87DCCC019FC401041430F594B0\n"
+":4055800088CDA4EEED2ECAB5137634BDAF522026CE7C4049E5488B5FA42094D627C23AEE02E57225A547117BC1A8C4049A40DE833CC0C33B035861630F0B62169D78B55B4E\n"
+":4055C000A208F483C1494C1B46F082E896429322C34227880008E9F513A978E190412008623EBB5F7C465921D2410244AA10F280C4BE4E96541D2E6C5422F4DC2252908C82\n"
+":40560000A0AC155500440104E44A04CA4112824A1481AA0F14A0F632D08C22941FEF37F1EA1FB102C7A093B3714BD1CBE3D66682607B05C100CB9EFE237C10F561EA82D132\n"
+":40564000A006111ED7E09B5C86CB8B215DA143C470020BFA22BD22043E1C3D82CA35FE8774EC96BDB0B0B51E4CC081860320B100CF2F343CCCE212D9086304041591B2E00D\n"
+":405680000102753D2D8CED60302AB268B406124CDF4221D6C6705642035482A7C5ECF951EFD55401B4050B7E91E8077486E882E40873AB0B10F47808BA8F94BC86CC209CC3\n"
+":4056C00094871D20018359C263ADBA1EA0331A144079C5105B866CE50708176801F4C2C8FB65A88C903CFE068E0E4F5443B8A4039D87F989E7BFB4001356A090340663443E\n"
+":4057000067CB7B119E0C42D36415B848442F0BF908806D7B56BA7CA5202039B04FF8AFC87AB6E906AF031E6D023AAC243DD146201754460901C9FE512B51F66B50F28232F2\n"
+":405740006181598EC4C112A7A50244A90630B82805FB6314796A1989D9DEC2037891184CD214212EC612942202CF72005328BC82783D9FA63CB7A08A62ABDC37880D219750\n"
+":40578000AF429439832F1726226B07E0F0400800539984C4372B2F3E983D101C8619FCB05041377003962A6018712E078D9A8453238381A7A5F74C00198AEB93C792AE89C3\n"
+":4057C00064530CA051647F9DE43144057B65187AA10840FC674262F57650889D034C3D8E7E3DA39C205807E426C1891317C396E243F8E7444102B98024CAB160847A42F375\n"
+":40580000326842A2B226D02BEB46D12A081024BAB91A0A428409208E2D92AC6F2300487901CA60809210C79293D416081B60004607E03801EC0B08CCB202EDA03F0FF30B79\n"
+":40584000D62A02520FA72736E11100D1043D73D6857144CA053744782063E230162EB683FCCFB13280165420F99E7AB949011803258D9001061402AC8B8207486347DD622F\n"
+":40588000435B235A83E47A316AB002B156F0B5B217F584D04601788CC40680446884728793D8DAC421CD8A1074A0F65CD908597A07783063DF1F0FED11A20C9000BE3E60C1\n"
+":4058C000B1617685A880DE7F2010347DC0610009440681A7B920229BDD79B2364C02F8613B803EF334107B638B2BF4C21C407F39CC267C81A4358F48D102478360A10380D0\n"
+":40590000723432183B6030A94118414220260D41F34A50F29823284204414313C82DC41972D2150A3B4DADE2CEC1E568C472D1B3096E163EB1221F58F897560008BDE54C82\n"
+":4059400049396E2042200D6EDBDB1AB6003FDACF6367F1303C6BDC39D2C206ECAE836B42D5DE99FA196C0FCA5B0873A5041B3441C20017F3AB2153423579F15890A07791B2\n"
+":40598000F8470A78DB4801ACFC440012140D01AD320300C01C779530DF4C00B97486B35909F02FBB0010A1A64547871C300C164E418314D502861367050C5E7C5842487EFB\n"
+":4059C0000080E1EA140A530006224321029C2D430BA5590A9D28680D06B8D040170680D04C653F897206018094DA0391D377A05001F130F09A232018014416B0FC462D1C7E\n"
+":405A0000689ED434BC85B6228645C10EDE19784FA7C0475860802A1972C7C440D2AA700C278012A1E38FB3313B518CB9B2699C58FCC708C8008029EA196781081A3957C060\n"
+":405A4000F9EE20EE70035C4C25FD6AC4808A42871CC388492A8500302E9D83B3AD443AF65BD9100611000278EBA0A08016ED8361D6CA8F72330825B1390F7725979DBA84D3\n"
+":405A8000903FCCC1C002217A885C40BB0D0EB47487833E540428758D507848D48163B45176FF70F80D744E924415D669240592FACD14CD9027AC3607D07EE3ACBA2F1022A3\n"
+":405AC000888D2823482402C0A840EA1D11AC200E876023632231ABB94548B90F47109CB910C0B24A4443378540C423F7690A07E864A1919C80144104BE01553B32012028B5\n"
+":405B000092038055C96F4FC676E45004C7580D391680087D96E639A2821844078DA20BC1BF25E7B601043CD9125E55CC10953C87853980D256C610A19F628B0FB1468F4374\n"
+":405B4000C897B2DB88D002326F048B0289E098C03400626022340062C02334006F6C6D14C0905DDA9FC8E0F820341CEBD5E20C840F6BD5931EDCAE1EC0EB2B58863F880838\n"
+":405B80003C4B0439EF227C906410186B065D3EB441D763EE899F8D904FCF018608D1EA06E103644261785F90BD4C8443E89871F8105C47DDA5A840B3B65218B5A2C8C5D8E5\n"
+":405BC000BB05DA22E6695E207A6391E55F04019CB6501E9C09210F4AE820173172110CF00220CB5D5C3DB64A7DB9D486CC705ECF814F55F28B024002410E01465CF0E0FE35\n"
+":405C000002DA702A8B53C05925A43C3C610171001F79168241E44C89F4805BDA47646B1F44314BD677E5E132D115821180860C7C65A021690DDDDC43E0897911A204320567\n"
+":405C4000BBBB89123944EFDA728498287CD31020E63452AE8010FCC5182301AA761A27612A3B8F22A162301AE7590C358FE2A94E301A675765D5880A3D8A84A831DE9B92E0\n"
+":405C800022745D7080843019DDC5244A83C0DC308060C865EBD6C40AEA10270B3AD1F12A402043BC1988082868681AA6A91A02811D0AC63E9D512023CCD0D2047403C49345\n"
+":405CC000BDDD168E3D88A5A5D91422657774524C12D53E43B811B4E610137320B1DBCD2238F6206975AD910F56BF43BBA284C24C0F598C061DC0DE2A0028E6F2ABF035BC33\n"
+":405D0000CAAA3D7EEA32501393EEF582BD44481F2C4E8F77449776A8106D1889826B1723F06B8D1C002176D884049DD0606A96C4A8B213775BABCA255A80F604128F902805\n"
+":405D40001B4F9DFEC582607344980C903E9300A203C403C5FA0F0177BF1407BADD10291026DB11EA22DFB6261FB024DA98C0231300032F8428501E40E42CD000116A6F3293\n"
+":405D80003D81C803A4A9F23C19DCA7F0F75B419EC44E2FFBADD088E238C12D4F9F31120809DD6EC59AE82279E005F75A5A168E8A3406D80A5DC2874CB18B00F015D9A904D7\n"
+":405DC0007CF75A59787150BBAD0C43CF52280F67488C787642F21210EEB361EEB4B5811EEB3D431828B21E4709869F81294591F52EEB59501ED6A5C903E12EC315CD0190ED\n"
+":405E000009AD60CCE832741B2743DCF2243CC09D2011B23F97203EA270C59F49930877D9BE0549809D0F89D0731408CB1015C092D9481CECD9F37F0F143BAE08C76521D911\n"
+":405E4000901CE00E6C0009B6CF06F70D52E775C395E43790C3039749A618C2050AA00087E7E0C1107BB87CE93882A7E12000F875CCCC5EDEA41217CAA7821AA009787A1C13\n"
+":405E80004720AE4E605F40210B03AA010B6C21E1E9A272337513C242F513DA02021B66620078BC192A6C8FA3E308B1304BD2E0E20140CB7EC769820F300843CB13F25C9D59\n"
+":405EC0001EBD901007D4D5C5B0808803E71062EEC4E4BC14AC7DBF7077340859DE0A08772F72C1A1A57FA0E77B0899DCBE88F562E25DD8C078046415F090108544FC884839\n"
+":405F000068212CBD99D08848CEDDAC425931A8671EEB6F44041F53F373B0B8306979E2C858EE79E2ECF2B1EBB04204AAD88B1F3B9F969F847A20C8BBAA60BCCA7626475513\n"
+":405F40001D1E75D8C10821B21F90202462752A950358C4EC3B6400D2B81AF6D3389E1DE9844091A182DA813E719440692C0D7592D0F97D707BC9E4703F0C30F7100082DE52\n"
+":405F8000C8F7205B99131841DD6E4981A377BC292592416421761C2FBADD4441EF28853CED72443043E2ADD1063C40B25DD6CA3D886A268143D607E24A6A41901E3D9B6200\n"
+":405FC0007EB8EC1083647C209224F1D6879368CA50877433169EE0BAA88C41A942009449151264B5DF66484BC4B04752742C6CD3A2049A1E9B8699315719637410264A5DA9\n"
+":406000008E74204F440A16A1DCAAE03AC2607DAC7043D931EDE0A2EEB8D400B1C432484B6425016590359C56596C843786021C9C0B6100150281111C2292884FDA0B2608EA\n"
+":40604000117B68E888B08205793704D922C9DF1976082C2561C70EC4AC20822060840AF65ED11A436788D704062090F39EA0909E1CAE2E92D61003D83AA4381315C8628755\n"
+":406080004CD5092042C40F753497939A489D63992C880812F3BAF127463CBED22EC0409FC698D3A4FC43C26D63D53303E3F983133B431871DA0438E684A1CEDCC442F52EA3\n"
+":4060C00010F53000843E12B34043D12391E66C9B1E2C1812BB3254BD02BC32502B8203AC05087D878E23C89E57080768085C905A1E411141E02014E82201063C41E83ECB59\n"
+":40610000F0206B667013618E83131003BAD31733A85850706683393FA20680A2191D2619D40EB0121048144E95CE00C7AC82071F741DC08DAC002B2E004EEC6A32411F191E\n"
+":40614000D095ACA0F61649D023D628A518039821D54AC571D813A03C887D4F665D8AAC460488C53D45294A1113760281F547D1771BB89EC23F760C94890F0AE14F30501E21\n"
+":406180007CD0238F0E71903081182A307C0DC43E120B118CA11808501B95B415AC874130225EE58C3DE15D3DD74C625919DC7C88E5560897A0CA112F2AF044BC958912CB23\n"
+":4061C000467B6EA8CA047030010A028164F801D72A2206756778F700F8F7FD90F75B1A84E8885D77614103C090FDD6D943D559064ED251EF1F020487A04443ED5BC409D11A\n"
+":4062000088BB91113C090F8088823CE98A4D8094B9441500843EE3CD2274A01D432EEB7E23D898E8E08110FA03A440126420B2117669C881C391641019842DEFA0661040B5\n"
+":4062400051EC42DB287AB21CBDAC2E2C005DD6F67D42E43A4542F5CFD1793420BAD6E8FBAD0CAFFA03F5BF759493801DCB160ABBCABB96AED2EC6042EA4BE2861303667085\n"
+":406280002EBE172C81839FE5C82E4000F797D10EDDE49424177148984BDD618D0F487875F86D2443AF75861E0001281C7677A1F0F2D090C30ED8EE2208F61610C310E3DD30\n"
+":4062C0005C03E768216441D8CFCBAA6A87BAB84CA6EEB0C44A656F5C358B889591DC58F9C460EEB0C5C824C865F759B890CE0432D14CC8A66DE7CA7104FBA6ED0340A6036E\n"
+":406300003408E3D9D12245DD083D2C922C026130281292E4314599042607683C8883A0DE1F298D88E011E6000FA741C5816C25000943002313B60691F3841A00100A4A0C9F\n"
+":4063400021CF806588652E078ED2351DA300711C003D2531E8DDDA320C712A4F004FB7560F99DD0ECBEC5B047101E1B52320637909B9096C6E622D826618E025F756DB015C\n"
+":4063800066D2F23108ED1A22C107DD63063C247F2A24FA3DA84FE79ECDAE12548020EE901A9A02B7C2CA0269FAE4244EC902BEF18B10023CB9F6B080041775829DCBD02410\n"
+":4063C000F5768097DB37D8F758290FC88529D80F0582040E3181AD04C8F3AA32038BE852EEB051EF2382055C859028FEA9B20350BCE8032F4FF9220401C19639B1F108F9AD\n"
+":406400000387A1606476F74104DE9C33202031F3D861F77608E00902AB291C823D7CF08E075761668C0C0037348881A8921D493084026DC462206B10440509E0839F0B8FC5\n"
+":4064400059B10885E004A1063AE6F0F9C210F530B10E46498620F8787CE2847016E2D2EAF3C26C73F1CC895A2876FA71103D4DC63B7358E34680380BEE2FD2094C0B31C4BD\n"
+":4064800061300076EFD1793BCCBA6DF84160082AED39F20948CAF5009441ED1952EFD642ACC2EB5501114EE27C090EC3007BB0BD8BB5760C2B04443ECC0C1206D44040EC76\n"
+":4064C000C503DB3C7278F84B584653DC85C6001CDCA4484E64125B25F0F84E484F015C76328F015C0E3FC9110C093ECB0CBCF1F38EB0F3F60102C49ED8A91F0C3888247E07\n"
+":4065000060A30208E0EA756100877D822CA60021BC85B9550D001989DC7445E7F8C120BC64C0876DB8104C2C601E2CF1A10E2FB62E68825221B87040100D0D952C70B50498\n"
+":40654000980EB32FBF840A870852A430311CD01133AF203100A38FCECB220254896930C403E64DC4050BF919222D922209B2018E24D0EC25816228400881220861D62282C0\n"
+":406580003B8D1B2691873339983ABC6101081103C8151582D829B08DA800D470401F73CA88894DCE8B0300601A101A1E456F11440B0242110876068F0138093F4B0EAB9EED\n"
+":4065C0001CE26100BB0D90431A7264182691069C87B960704A630015200FBC21869C9006049B64018480094B998B02D48040EA360DADBEF91C1D0010D081050C1A5E430895\n"
+":406600003F4B8E631C2921D9A7622252E7479201002C752851E3A5213440A1B4B4D6068D320ECF002F07099CC820811C430C1EE15D1EA833102CF120045218E102C17ABE0F\n"
+":406640000AF713058EFC071ED26613108608A968FABC94430F172B9055D3FA63CD3F4802F4E9A082674FB704CB1C7C0247501DD68382297AFA5D0F2421959887B968C4C103\n"
+":40668000F630189820A9D3DCB4E26082874819AFC1114BBAF712900D251F1FFF8FBB8C04050A431383D60B43E9DCC2B440EDAD49FBC58859E5E5C252FA772880D0FC1011D5\n"
+":4066C000075347C308C2669EE6CF8061101E0BD1E43D02C3AB6095C4643B7ACBE440331821F1F311461044A1D46FA3E5CFB108FACE1C4050243F00E6040C540594E05C1180\n"
+":40670000398074792F40A3E957BA844B774328C3389426020175B2C54DC3421A7753019E18B8772AF186D4594090820EB3AA8828B3D8847E7CF21EDDDE103B45583D684A50\n"
+":406740002677680C90F068FAD184418EB2BE12AD0063715A2F31F1081470840691B9BA2E088434064388C71A1DB36A24C0265596C00E8124443F0CB58B0039C47FD6008156\n"
+":406780000011C2507651A91E27678DD7081C012085864D633C1C033DDD525DB3263E43321C6A31B0ED0ED36A462ED2D42630E17028131B1DA10E47C6D7A258D3A0D2317A36\n"
+":4067C000CF147049C6CB3E3D655C3392198645D62003CCCF66721EF93F160E0D5D1135320886887022CECB4EA4437B6E84687177AD109303978DC00FD21A05ED0B72DA69A8\n"
+":406800004BA06587645B21F0B040D12B309788B106256A248855185691060AC9606103102C111E001F12F08F8903C8D8EAAC41EDF6F12B8B00639AE7173A0510641B2BE116\n"
+":40684000871C7882234615512C21840848640C00206CB1493BEAEA121001B2CA14401409441000D966A0091EAF142F5A4788365AF81738CBA8318F02D99DA1304BA2D90EDA\n"
+":40688000A7AB116ED24851B21C472F4A81881811F2573AE003D3DF5B04780114EC4013810BAB444A82102E890D5180B400807E293A11380B327B2278478ECF702EFE212F6D\n"
+":4068C00008298E59116D78B3D36A739346354C2C0265996C068F05AEC96653B17A15A0411EF28F292980CB3D65D4543D09296029096001036DFEA00995A5B797FD27C189D5\n"
+":4069000043301E1BC1007C30347CA84E6B28712D0D8962ECA0060240966513950D7E4133B79E0CF400217A30F86E787AEB1463C42B3DBD9C0A20C01F20204CCAC20C1D6DE3\n"
+":40694000B43220134082FC8310C21F41921009D5EA445D9C47910B431EEA9241048132D2B2876C339EE26C203CC606B5F8847804A20F528E0887DAF885291F26B20B8EA9E8\n"
+":406980003C7B3D00656068069BAF089054750EA5521300301A4F604A4C8D4831358F3ABB3EEEFE10C00C04CB19D000A20C30F7BDE084C479E1E84A41EEBA3114BB313469E4\n"
+":4069C00093B488A85A1E6BAC16C324C6D0A7A789470A68537021AD0AA75B3319E1ECCA612CC8010FBB9646A19299113400AF0063888345100249320003A882602D5205F1F0\n"
+":406A0000A421C4CFE84C8420D11EDEB832D2F28431AA0549AA6C1E00B8265916C804EC80E28961382A906CB7B3706C38E3D87663842CADEE363202D90D8E7CB466A278032D\n"
+":406A4000470D948B73D61A8E7A662E84E819621CC33841BF033209B3ED3923022634A187B579CBC917E3EA92A18702D0803C0521C028A085D6AA840703D408ABA910054034\n"
+":406A800001399010AA6D1105007D9779C30DE385410C1D2E461843064132DCB6F71B616E75336086A85976FD58886E1D7C202EDE19631EB70D3A084077305E1A128011E04E\n"
+":406AC0009AC1002465BACD17AB73C4AF2DBB92AC80204CAE2D903A08D871F12E20F62170C58970010143A84118806DAFB92852E71BC2309D0186CB26360840555F605E26C3\n"
+":406B0000C14659A213B2036A00ED0655F66432400B012A423500059D7BA1B9A48801E83689F37158D4E1777DB8B0068348E53F0E284006011EE40290446C0C3AD8C84A1052\n"
+":406B40005B15716FDA8211FB505C826F5C900D6A941804DDF8F03DEE54245DC0A3D8FE240984B56A403CEA8342584A211404A6CEA42C04820051E9F1E1093D72222124A440\n"
+":406B80007C8390205D662201A800673202362005671410905582207C20987D83E820BFA8694B1DB080C0996A5B77090984A41004019C0431E859FB4FC8CB8EB6BB23D855CA\n"
+":406BC000D9A8502DAEA113D84FA9D1EBFA51ED7D61072247C4B2A798023AF3D22C7BC8D08F02579E4D0D2C01D11EC2152EB76F2F16E60E0248202287DA70C5CEF8879E1FA2\n"
+":406C00000867E3AD92A68E7311310CFC4F1820284B6563AC041A12FA6CE4630980925254D0986DA640F7000AC48DC50632E02A20C01511296B0066E12033F89768030C0078\n"
+":406C400086F6E056B951C13A3EF9AF10A0019E8C014F6303163C2A5632439DC7075831862848A35C97D93E8445EC9BA1108712A3BE4C0A1C48309D09F8C0D4FDF25A38C1AF\n"
+":406C800062C7C05DA000FA12288F443BEB38AC1E409955E042410D404306CA043C02798352415F105B6810ECE2A3E0E724080439C240D96D00193B2C8943084009647F98BA\n"
+":406CC0003E8639440C0107B0C4A04F00118A41894039032E7E0BB01CC6E11CCF81D488D2E417757B889C3F1A3EBB94912FBE32C6D2E3810C4D3EA7511034E0083D9B826021\n"
+":406D0000A1A0330D439636381CC6306C74203446C45380641FB2E10423C7902478C41C1E001F691599B3EA7C91B9F8003BF44CCA3C4E503706081A5E74F71EE36C13C3C857\n"
+":406D40000A12698ABA2D23C044001EDD4C40C0E8876ACE90BF318F2B6899844045036DC1D1B51C0D0011E815F4FE2188E30080378A4393185B801AA02364F804E8024610D1\n"
+":406D8000CEA1D5CB22F4070A7A39510EE5C582248D10E7C51E8780640C0DCAB0402204E0F70EE10FE3067C198274B429607959C0C74E7304226781550874EBBCE3CEBF31A9\n"
+":406DC000369C97A0780482034A904052034A5040D3B964BAF2B08DAECE4033D88FDDEB8B61F619189CA41769BD09069C68F90ED4802EFEAF21A26F28F000CE543C8BB82461\n"
+":406E000023611A1CCAA26CE81D32C044001603806620DE34F9487CCC61C870BD8870758614D0030A418314E8997DE4D220BA0217B9F0CA287CBFA2271B1E5224202CF78CF5\n"
+":406E400003C06EBC28440CA5843BEAB90C46051421601A4ED5D893208A01151344D943D50FC6473B108A7E936F2A2220F0D0790EE802E3A12007A084EDBC7170A3C18716A2\n"
+":406E800030E3851110351EA7A91606B3A4723C6FAE16071C2B84E2702464906808417411B941021DF9E4704DA0C4A02E090DAB28A403A7201F06F40975D0D2840CA18F8CEF\n"
+":406EC00030EA051A1053079960EF2A065221EBC6A1EC15718D201B66931233DD86B3B34F91EFB7C421DD3BA2018625027A4FE54A4E5F1B218658497339A10C3A0D68F942B3\n"
+":406F000024EE386670794AD0726A04F630EA442FC473A44CE40267C66ED3A51723B2EB30F68D210C04C140106E380B75ED1182418AA5A3C0340181BEFF3A106C44F2BFE1D7\n"
+":406F4000831D40283DD7443DE296470131B56C1782CDCBBB24487E045828B76F81DB2687019875D2A0901DC4927E0C8D1F5D85975E7910E64559FCBA41C840DC4442068D48\n"
+":406F800074FC6A300182B4831600B086CFC58F8C06371A3206EB801A98062523BAA404D03432A38418033D259020D94B7F203005E0FB1CE324CF33E3091094A88265296D7F\n"
+":406FC000E18E53BB68023014E808FDEF62567100F0C2D8A744590D843F73F30D9C06B204151AF0ED8F5C509023D5C1223C6E668367021E92D776991BD778040C95A40030D1\n"
+":40700000059BA41FA1B7076F7111E0B42001526020BFBCC15251000769363140B0860D80224DD00C1527020DA4C10DA4FC4152A020EBB30220375A39007AEDB8F693A1058A\n"
+":407040004B08A1EE5C7160AC486C57AD3DC582E12EBA0B160B44BD686843833D8A585DEAD45877820858672C0841640560E0180700C8601C80BDB90CB0CD082FB504161F16\n"
+":4070800051F1197086462F43A090444101E027741B1799DE52F5D660831DAF5E22077300213881B00276C2016AF10735D67B566C7D61F73D9EF688E1B81D97772C8900060B\n"
+":4070C00096C0C9C1BBB51FAD534B0F3C66B0083424141DC27A44175B960B1E57E01064D9F562510403C0AAC588800218B123A55200C01215D6C86D3EE201FB8CC0581B41D6\n"
+":4071000071CBB51E084A3DBC46742051AF5BA011238D3C30A095C78072778028924138B0178863D96A138B3DF49620A8062204E2C05DE0AB72116207C6B2842353C5A9C176\n"
+":407140006DD74876F9388174C0BC7BBE8B011000131A5BBAF982D8AFC4511B417F72F310DA2B0F41A1A227F797990185D51E20AF79FB218EB7CB1D9984E11D112D4358B158\n"
+":407180007E60EF4AA2651EC218E231754C58FBE9D0408002D0C6051E26DD07113FB623858A06F2AF751410E7E3E2531CCF8A8944543483118812A88792059B1B2E0E51CC10\n"
+":4071C000EA08FA09AC6A1C828301442F6414100CEA344801E0B530041A0CF544A6600345A141B4F40EDF6E4091185020097ACCE84121F0A070048842810068408A1160A015\n"
+":40720000003C402C5E072A4322F910F362564333A12C35080E011FB53E8812F3BE20C2876CA28EE2B633516E8DC606CDA3975643701645033A23A3A66200A40063C51AAA24\n"
+":4072400031C10EBD181283AFA347166980A4DE824458604A63C1A0827401BDD9423E23CD3D01D8833E414D2D36891E0180121EE016004CA4C5BA7DEEF420083D0C5EBEA0F0\n"
+":4072800020407863B2A7073DA0BD7850200F804D48F6F23DE1077E0579418ED13130D3C40304187527A89843CDB0C050EEC732F0F9D8F2A2E9F45F608205C903080381B5B5\n"
+":4072C000E783C10AC9702BC016E5DAD36402834078500D79658040512829DE3EC76D87106812F5BCD092E358E79B40416F595B885A7B8184B85438F55EF8840171EE64F74A\n"
+":4073000067B98C4051454D4BB863842727C06DC0C4410EDEF21F173408142B4580E40513E53201497BDBD6424F810E42128050090905802FDE66460C77DDF14E820A82B581\n"
+":407340008616FC01F2B2C6E040F04A60F6DAA25BD74A00D94E587B616C80105450280123876C1F2B22C05D6C543DAC7E4049DCCF49D4084087AE0E84B004EA9440108FC641\n"
+":4073800050025D8447481162F2BB8E3C952335841DC6A820A9860965B508E209F922708F7013213CAA944010445ADEF707D185820994F84F83BEB18483A0420192E2574417\n"
+":4073C0000C890A0AD864003F06B60804398A06D021EC0D22CD2E1B2E007E0013C068760823270AF580CC1000DAA8F002B6EC910147A34C7A3586A068B80F76DE5110CB8DBD\n"
+":40740000D000FABD5064805323CE060B82038D67097270836549600C1E445D361012A8C7C097D20000D308F7EB21552801D3510EA08708251F40210DDF8169A2EACAE1001D\n"
+":40744000AD36F27A8C01202D38A9AAB071F63C8183A5E8C3414FC549E3E976B108C750087524820C6AE014FA5E04483EB64B236294903085A460C302C0B873A1C3E0AD137B\n"
+":407480001DC2034FBD250BA7190C0BEBF5A1247C1BA43E2BBD1054702800D9880BD1406DBF0CAF0700049702BAAB80445A405EE8D1164013402D02062B8B0A97944168A2DF\n"
+":4074C00007C90965D899423460BE104AF201F236A0E575881A37926418DB1290C240089BCCB09EF76C459342CD8409080B34D02B788F0184132A6D2020AD53974EF689A321\n"
+":4075000018901004CAC00C29C2430182A1236D1B3F4C84860F9E7B47A51147CDF68248171A7411D9EE8A3CA60100BCE9D03E800A1EC19A4372282EE6442D0B010965E9C049\n"
+":40754000489E4289EC05CD693181743C537220414E020215861982E2221E41AB1EAD2720124091E41CDF182237854586BA801AF0A8C980F1A91E27A79677C44ADC97458E64\n"
+":40758000CC9211AA89A60580A00E8FE842C0203B010813C029CE4021EC11CE62424254A04E3A6460D8491A611AA99E4030F3390081C124ADA2CE39100AE182F21830F59BBB\n"
+":4075C000E483DEF6F718710046BE8A5F1862EBF701107C285222167DE988005FB98E88D1F7B491B1E5F3D1280B6F3D2610157C415C621EB3201246CEE3E4807320462F0AB0\n"
+":40760000749F92004B56603EAC6240F4F165D901C5F0A0785A2080E340C01CC2A203DA15C33110EC5C4C2607200FA0D1340BA0904A00400EA53028D2F2712888B80C44067C\n"
+":407640001FC40F2DC9A38C9C02F0C77070500E0C50D895C4A3DAEB44AD257B26D042111006C9AB1244E002C1701811EB94811836659222009F7DCE978B55C4983D8018512B\n"
+":407680003DC89180BB18460164E7F243A9F9252CBB8264FD2A9642081437F99724402F145D89040E00E18104610C5E5C1010089A130D326BCDB1A5D9AEA3E28CB1368A329B\n"
+":4076C000E88E20C60F36C895668917E487B3A640069A0497B4290772CD31C8E9CBF412A07EEA58A1E80A61B5F8F7B110F7AF799C24C766558FA2378401288B5064D8F54AEC\n"
+":40770000F8863D587826810B2B532C3CA585E419F23A0F1EF5164CD721903407C0274A8E3B04288B6789CBE657320C7AB3C8862400124412EB2DA1042EEF130CB104810E61\n"
+":40774000F4FE93546DF719D881E48825A10A104BCD46C2097797C9764429794EAC8D01B7BCBECC04F00DE17797D186848821E34EE2D2C80ED5963DB4463D714525FE5C00EA\n"
+":40778000F8016C8D017077263A126C8D01876888100B5BB220982E300EC08EDCF6664A00077984176CE81B91A02D7798391117264B3D334222BD96864663DFAFD9C5800B1A\n"
+":4077C00003F8823D2F6C3D81643E573E11480A11C2027FC1A8E21077985A45A8351C46A8980C17D73F010A2077986222D428B868F3C447E849A2BBDC24654B8182FCA043CF\n"
+":40780000AE3D4443F239D20030C218F3DBA42C001D048640F200112409418803D7D909164091A01C82003F9EBE04641E062EEBE62D47F948407819630092A7A8F56BD90542\n"
+":40784000FEF2D333D38556CE8750490E8A791303D1E0640715559E1DE666786D80C9A852F8043CC1E34417E8521222420EF32D43D93CE5DE9A43DD68420EFA89A0B7867424\n"
+":4078800040538431EF17821D831003CF4F846883A6A811DE65A648A40B5072E9817904BCE8B857FF0EE8485E32AC433348C4BDAAD0400D1B30E00C8D07A20041888F797BE5\n"
+":4078C0001EC408225E83C044BE17C421368E40426D88B0B3CA858C9C410987C67423470445E23DE6108742D09023E006E124019CB5B2B1281A27BF79AC8F7B930EC8125DDA\n"
+":40790000EE56200779ABA22C28753C7281B9470162B10A4E8A64E865DD6D82361E15180457465E979490C7D6D4A2681CE3B756E48F7939977999A1EB4ECAEF3343318D0351\n"
+":4079400086BFC0D6387BCCC9107521818080DFBCCAC4B2EF33154AC522A18149E493C2EF332549C50268D032E6C01D48BF122C0880CF79701748120EF23281194451F6C540\n"
+":4079800010B01C21E3766260D730897013B399CA87179C41C402EB75E110076EF33123251EBB671080F12AFADD687BCCC0800358B7EF32F4C1552F48238B5EED09160A94F8\n"
+":4079C0008AF605AB02C53D6EEC5DE660A89C968DF07A7E74A879942A9DE2EF278965DE65C874DCF081DD413022F1A24FED8B62368004F9B208779992DD659446B92BB28EEA\n"
+":407A00008F4DBA0EBFC448D3D810EF33443C9ED02E5B93121ECA20420C0AF378A8DCC84802EF3313DEE7C618CA94F718811FBA18B101C02A2BCBFEEEC41EB82F3F391F09DF\n"
+":407A400003E0FDF4003136CC81DE14C979D184A9881601CEC44433590F50663E687ACBD1A44897D71610E22D7B973CBDCB9A4680EC6EB1B2B288EA89A0359201A9A03A6C44\n"
+":407A80008B623A14050766C48D140DD170481103BCB116604FBA4C7BCB184B24086D0BB977962975AAC09A23490230770251894538000C77962A20116218841DE4C85C0F09\n"
+":407AC000E0BD67A03DE520B07CADD2E262688A739B35100291506077946B8010C334A18E79137831F7659AC7D7877D8C3A0973C7D1EF28E4C5451EF283308FBCA004C0CC13\n"
+":407B0000721007BC9B92C34E4E01D6E490411F793588FC0EF793610143F4EA0C1143383FDE4DAB4200664367DC0E109000C0F2F4A420827DA5F04F137008044260175FFA05\n"
+":407B40003A84F1F45CBC9140713C100041374098118C0CE7BE19A01375FBC17C058E24A7B4F587BC9C9303CA68F21DFB9C58FAA974426D4D80F7927181E47033BF3F1B004B\n"
+":407B8000D220789C0CFBF4892F18CB9F5BB021C06A8B80D810965EA3DD97C58118B62022D17F2413701B42D90C04262011EF2EE212F4E38225F80EA0B5BF0225F01A4282AE\n"
+":407BC0002D0A308965633DE208801C73033EFD0843C63866071B50E5EF2AA1EF2684040C3F05DE75839F0C8F7938240015618F46B6242B063B902AA1D5DD023A851BB1F8A4\n"
+":407C000082E0BF78EF8E3D913012EC09A12C72E58AF06031C0B01AA4880607EE371E93112200D6EEEBC1B12012C3D77761880471F78F00F68FB9DD3C05F90A201101001540\n"
+":407C4000DE3B060BA81EC097845044BAEF1D64CA04F6FF8100C720A370DF1F0652161FE0600332FD795D3DE3AE33118286815C9F40610904E8582454F78E6A6D306F9C24B3\n"
+":407C8000093C291EC7210BE68C53EFAD920944208449F036E4F78BB8EE35E5D8EE82009C6709B838CD246E0E70647900DE692F21C41BC52C07800E6D641F9100380363882B\n"
+":407CC000766912BEAFF0105B20E8480D1AC0805E6DBC208BC715480005D0500D8F450105D0DE623D9404103785E008205BCE5123941C380B841B3D8B050CA101210D2218E7\n"
+":407D000082607BDE070428E9B50125B0350F7886A607E8E10761662207BC6887D88223D859C3A75A1037AD8407DC5AE2048406878491C478C854126B0151896388563901A9\n"
+":407D40007D583C860464445D88C0418F6605A0181320798C181C0388577B908DA148801A006CDFDE225F8F02046A1DBBB738F71AF1017BB60879E800B0708263814040D3D9\n"
+":407D8000A0EED84361B370758331DD33D3B44B4890C90B1F26BC0B1D8B8A23C0D811759188EAEF67CD8423EBD521DC49C7B9BE444D364B70241E068A02E48BF2DABA06C638\n"
+":407DC000E3925882C7C9DD03827400738375E4336BE054721840DF7E4E902A10123DD95424116C86CC562501B0119E20A9D4539D013D6C91A21EF45C8D79FBD461804F63E4\n"
+":407E000002C8306988044E7B9480671FA54D87BC59CFBD328BBC7ED4B6F89C0781B8DC61F78FD247A5540778FD88380B2241D8E0B39284C338B76254012EEEF51E8A2D1919\n"
+":407E4000C9034429B97807914D1EF1522F27A489C0C0E6816DDE3E420DCB1D0452EBB5C16FD1E7C23075F530F78AD9FA60244E060723C09AADE4C575220CB8478CAE05894E\n"
+":407E80007A22582DDE3C689A407D9D025C1E03143BFA8700123DF5D05D64C6213150CE41216010419C0143B745184C5A3456236E601E7BDF106A6C3A1248403A9D2DC9D0DA\n"
+":407EC000BBC43C410043D3A5E3D60A445D0905454D96EEFC400420889D75B0211D4DA5D12F45DE404223270C6C880A822F5EAB9F7901901B46530ED0EF2014778491EC0AD6\n"
+":407F0000B1ED06D9F2A6F8957A3419D8F48A713B7306C5023C6CCC4042587A38CE03C80A3A8919488053E08865D091A798130F9F518FAD6548009E111C5002220CFF521CDC\n"
+":407F40002DC859B262D0E5D698856E5105AEFB12D818E99344030D7CF247B06087A5E38982DD005014EF0FC4BBF46CD8F086B8EF07A37ED9F594E8803E8EA22D3E78F78705\n"
+":407F8000E9026A406A68A976BC997819B8BBC3F481736C7605A28BC1DA85E89EF238001F08AD11A06B7787D95A3CBBC3F4BAB3B44051C86AEF0FB431408617511ABBC3ED0A\n"
+":407FC0000C46420C02E67300AF6ECF08A26919BE61F443AE0C44021E40FEF0F35E75800CBA120D3319CEB041C8024B1FE0145B74A8F5E5D4F8A164400EEEBA2B9942CFE29F\n"
+":40800000117787B18543EA402100829FE04D11103BC184A403D172A45A900304A00F0263C2248209EC7DC20BF6BBC0923D71AA6C903D66485DBC3A3DE154983EC7A461C4D7\n"
+":4080400074EBCAF1182C9E86BFF8ACA038354052F0A2589A32B4878089580565D698635B212C369819140613C0363409734783850E4C1960EA2BE5409210345367E1183276\n"
+":4080800020BBC400401ED25A2C0D9018E8184761AF110FBC414814509D8872D1E70C491EC6EF779111E40183E87AAFEC44DC46C340848263BCEB92F269D94EC238D4117CB9\n"
+":4080C00005D66150FF50880472B3011403F45DBA03002E007798B258074A5423878261446DE7F6E3DE1F07BD0511A03554B04FA58120CA9E83EE234064D170900278860727\n"
+":4081000007787D2004954186C18C87959D87BC3ECC621D814510148E59AA2FF5DCC975DD18F787D0F8357C823EF0F83ECC0A161967DD7625D982085C6019E023DE1F07B78C\n"
+":408140007E0823DE1F23060083036265A100A209994E3A8EA55C06AE023C43CBE91606E97ACDC0A0E63C947045BDF3C9A41ADC94551C1DE1F2C8FA6885E44F8D4208607056\n"
+":408180003CCD30B379AE204FA30AD0EF0D74FBC3555194D1088D208A6548D30893EF0EE6BBBD78E6113C4E7344189B8416523ABBC34111154841C0808778941E44F238126A\n"
+":4081C0008F02217B39C889CD01A21DFADC97789525A5AA32111B9E8B02F170608260BCEF0F644175204FCB1C44488ABEAB0222A7A2698B44A654140DB9BE24087787C969E5\n"
+":4082000026CBC6B3264861521EF0FC1F808A25828800501C8F22E54688EC09B937FBC3EC4DFF78A811B19BC461FE78811A064781ADC8981347A0B3BC4048EF0109811FBCD2\n"
+":408240003C844340E82C084861119210907530EE1E4163B43445C049484541DC58209812F6F3B2604ADBCCC98133000130270F4167787DA2161A4597787E1104203D01EAEE\n"
+":4082800085101026802804FDBDFA3DE184643B05E1EC00F78621804548817C789716892BD790F5FB39941DE18AD75BBA1072028FFDB8212780FC04092008A209F7873A7EC5\n"
+":4082C0005903100BBC3A502A820F27DA15ECE94C86472FB0B88C05AD40B979C318BBC39D713B657C267CE1A28347AA241980D83E55D320C1AE3A5EA4008F7873260BA00886\n"
+":40830000AC13F69A50B1DE1CA81A43884695FC41DAE102CF8CC907A3B9841EF033808060B8E408A1964E7DE1CA610A9819DE19C968D44BBC33D139FC50867DA6562688C17E\n"
+":408340008A3509025DCBC84701427A10C4B63442208D71689F0809E048700C0F41F88FF596089E43D1A02BD3A1F5FA317071C9ED0DC1F40870F46EA902FAA411343B43D0DB\n"
+":4083800043B04FD2ECC219542882B8A2CBC86605E0D9C2D0FD964541101D03F47D5D1C351B023E427086869877ED837114813D1752011FA9510F813D8D5B91A01FDE54192B\n"
+":4083C00005A2150E65523BD56986D29100C92070173107005EFB43112F0C0648F502BC002481E278F2C042178F001012E07D0BAD8B1B094C65DE3D6A02F7D1957700183135\n"
+":408400000711855C094598C1EBFDB2F828548051007FEF42033401BA8C441A51EF13E6742D026883379D17789EA603AFA02240869C0BC860582EF0CA4784071E05026060C3\n"
+":40844000472138B21D0B126160702C2221C17090E0FF84130685683DDE2B461980840DD622C856913ED80F020322B534084ADEDF943010450C0A04FBC56109493077A81DF3\n"
+":40848000A90201A0A4C034008D939871EF40130845881468742CDC96205C190020C9FE579620633DE21440F7A46E17D61C08088E1460603009841E0530805C5A6E80C41817\n"
+":4084C000777522C3D702502EEE1423C006D0508F770799C2601EC5E1DDB52B8E4420FA33487C26A427E900298422778D4F844901414404EF0CF90FC15DE39C08206E82DC36\n"
+":40850000741CC202F8DAF0430E9B931F003A91499BEE4C1EC5A7310E1F06AD0C597BE39CFCBFCE6018FA186E088A0541878B6A8F03288C63A890681D8069AC0D75C15080C1\n"
+":408540002447A5E50983AB74161DDE80478042840883E7165206770B83344E5D4AA08845D0A1ED92F3140F0017C02E05E233610F80A3EF01E876F2497057F29524041F49A3\n"
+":40858000806108605023BB6107D3A54653060AE440E05D69B0C47ADD19D0A8003D846344CEF741DA1A79628B43A3104449E94B41F2EDD8E3900020DE06780CB1E3AE0D9A3A\n"
+":4085C000107BA3944BD25BE0C0313A704B0FBEF14598B0C750246148C772A88D3E01140E397180C0EA211E2781A05E120504B40BD033DBF6424F033B0221FACD646523E28F\n"
+":408600007E4308BA2E4940085FA8C50093B91C668A07B2902B0731ACD12B02320809020D52AF3D18885CF4710A3A7D74481EB21F11CBCCB723DD2CA5D77703AABC23033BD9\n"
+":40864000C441AF0AEA0922681463BCA80A3960783928885E08662054A04723A481EB0AB1F140A0819EF00B3EEC1B1C0081BB590836371643A8C7709412DEA6D13C53C00CE7\n"
+":4086800021DDC0630C04A6CD3220823A5AD20547825A958E964D007C792401807478820A6400A044508827B146098EC5B4B102396741D85E173E2E8BDC2ABF064201365AD8\n"
+":4086C00004A761B38C50825E287A1052084163490EDE2B11389A0833B088D71F09A2849F02771D7110F80A610E4000F0367717AA03C81DC0A584322CBCF3BB250880690EF2\n"
+":408700009790813E17C78901DF46880F00713E15F01131D04089A3F06098E3730EEF0E5380DC101C65F7793102891A2345D7624C13E0593210050028601F7876E86ED201F0\n"
+":40874000CCBE1600806819D9AB073E5C418BA84BC2E165E170A202061F2B4308BC4CEE4663DE2CC44C8185D260C8420484DDD2EE4408E02401C6D03070778B22C0C6FB563A\n"
+":408780007BF16132071150E5DE2C890F20A0263A5470888881C392E753123C291C25079CB50AB0C007032E8B0ACC001C08C7D232400136D201280131CFC286A2059721603B\n"
+":4087C000E45547946002A3C94C01F77BA1826082152A226F4BE60FB76F842014875EEC8E2F4E091622082E07D03BAEE587CEF027E828020085E037582E40D1E00D8282014A\n"
+":408800004220EC33E22182821142200F25175C7F91E5BD441006685DDA0375ACC8031287500A7300DFDBBFE219888098E25B89BDDF2040A27E0B3A127C0EF2FC51772A18C7\n"
+":408840008126883DE3CF813ABBFA0A7BBE38CD707122049F0469501E01A657A100A287BA2C118310748AB9F074F8C2061C0CF78891F0A42100054440CD5F70DEB710426615\n"
+":408880006D59480158BD08B047BC4A8B8A2C904C7633DDC8C5DB14840CFB5DD84001719DAB88B6E5642DEC201EA7F90180782DC11F073220040DA008A150E221F89154BB94\n"
+":4088C000C76D08E0B098E8D1441E0934F1E5DDF9E2088208692A899892B1C88003B1625C04C5C19BD8EFA2409E404777E7A5EA36B12AC1EF2C760F612121EB8CB428481E3D\n"
+":4089000080359A4A4E2671A20216209EBE48C990C143B83A8B2F2845A0C040C53A17B500EE5D04FE12281B0C904A2C04A6B78489C4D84014EBE811649738C8408FBF4C4847\n"
+":408940002ADCDC8BB5CD844D00094344CC26441EEB612C51400507B86BC0D232882300EE0389928BC772A201677D96A45C4822642366C961E7E0D100CEE238D030FC249806\n"
+":40898000448003EAA68A343C248C64063522BA94066B730007D73483ECC6322E0E5D5A90979D8C8087848CC581D0E9CD2012001B018D12E0ACF39258D0102E085F242E0FF8\n"
+":4089C00084958FD6B1A527000FB0BC473A60BD6B144391D3DD68E4117844387C6594470F950C44F62D8E3210F22FCE3214F534BD0F4881CC417B69AC40A09CF408C81F0875\n"
+":408A00006209280615E1078462C8221B90EE26A2E1004368B8B278086301F18410361FD9104621E8B01081021001F1730083042302211A0304DE11CD1EC6F41B5F808418B3\n"
+":408A40007592C09D24274944115BE118D4013522377E231244092D5C01F1B83643B589A41728417100613E499F78FF8DD7C008909BFB60E4678C30033C80D8669500D3B99E\n"
+":408A800043C22566CCD85BAD78CCE24682DB21B0F6CB98F845684B74624C1B0303D28022DFA60492A38F288F431311E822510846F845784AD02A0C1822830181428E200494\n"
+":408AC0002878462898D3A18D1A02E53D903C4161C032018DC3FCCC057C231490D139180137102FE118745BA46220CE0C854A748CD86CF136020F096EA00124012802500469\n"
+":408B0000A00940128025005DDC5C89920831A11621B456403B1881A41F5E46E390101A2100401345E64447854E47C0AB03550440D371635DBA221D5516BB6C4401887A2C65\n"
+":408B4000442AAC1AAA448E4FC466625700C06134C91C974FBA915CE1E12603AAC2139C0B34FC24886272441940BA8401ED0042743106B71E9C9B0D94421613A91E26CF847D\n"
+":408B80007C08D9F08ED0F84764BC26BC47807B82C0C7C47B3A9A7B8A80FC28485E14302F0A112582B884B203C7F90A06E4278489512090CEE71F41048DC9C17858F43341A5\n"
+":408BC000747DD104FDB8AC210064186CCCE33A8903D20CC20AEF6BA46802BE13B520281A06460F090C91C33F9085E0E882BF44365F6110100BC00147D32483C17B0F794FBB\n"
+":408C00001F23CE8B0050DBB44FA1B0E2881639061980E4367AFAA4B0540161D6BCB21808196A47DAFFC7B1B010D05B8D23BFB80A84BB350741EC5508C7000FCE9D2207140C\n"
+":408C400057CCC14650004608619814423418744AA3CA078B42164C60D29744AA3C732A0B2186C00C72647A2551E36D502D931984A5D12A8F1A0A6010032632594BA2551E88\n"
+":408C800031550D59318D49744AA3C9974D0A993187CA5D12A8F15EA83EC98C1252E895478A4541464C4C1CCE4FE4CAA04B26308913400C347DA65C3061C3D2C40C480C5773\n"
+":408CC000A44646087A2D4458051205540B619843A24E8401DF150B63B61840F63630F0EDE1007876C0F49DE4C10EBDE87DA0A13041E9A84163C89945EFC43200BA8BB88A36\n"
+":408D00000D87A11340F7DC9B92629F0F7B4D1021D30DC3D6948B8128006935CF0EA2F2370E90B41F311091DC051840CE7C78814081AA761A476F5134245C145EAEB220783C\n"
+":408D400075D2BF09FE0F0ED9DA0273F925F4C20340E624440217BFF48884EAA351390184CE44F78B68C1A1A6E5960E552EB4B67963A8BED502D600C7006B8039C01EE010A6\n"
+":408D8000EA2F55C115804A715410EA333598041B348C5EA2F147A8C248C356305B17ED8BD6C5DB1EA3072348B9EA30854B7562D5AF517B2BD46124582B15CD4D22B2191E36\n"
+":408DC000A30813686394A203F5184994CAC5236289B140D89E6C4E3325C0AECBEE2020C6AFE2EF8B8102CD9107AE12840C2E6A1C0162580DF491B081C901E5B2096EB1AADC\n"
+":408E00001207CC71E8800CFA4B88C2B008A1020D122CD023006E69E025005DB3D719A418001BAF10F5A6E110E80B8AEA2FA2189DBDAC7460302A1867F71104186C2B64061A\n"
+":408E4000629150D6128D513AC7895815E5F7ED6F2E0B0301AE33300B0220912C0682DF0141892C170F607F94C148DAED12F11E044D72B082BB8BD0F5A61082DD27D23E8CC2\n"
+":408E80000410002BEA2E4302C62060A043B0CCA487F24BD95F521BF3891B5BF699756B49016234708D4A403302E870F66E5107C38195D5AC4613480AF6200A77B0922A80CB\n"
+":408EC000B06A4E81A0237934E87A8BC0EF120034960C36E94129EC3020F8F00A1014583C577A2405184004213A35F8B14F01E45A6BE3C409863018F42FFDB12C38E1C02426\n"
+":408F0000E987E5B4E28256615E12D11DD290BD6F123E4A5846287727A2C32C2069D88821C4F504130B19E98761004182E140010689860008380C6E7AC60083CE20083FD740\n"
+":408F40005F05D72803C6D70B34E8401401CE987A3F32DE175D723CAA0C32E987A21112EA2E62E5B53218DCC821F745F3087DD18D821F74642087DB2D80F7FC20803BF5590B\n"
+":408F80006CC445D36748B0020B1D5950F2CF4714086BD34B2801039E9C4880C032542002B154E7DC9F02C855227954029B0818EA2E544C09F9E6642203753C6101A570323F\n"
+":408FC00050304DDA644F3512E0C22BADE0478288E1D6D9247738F05A92EADE93DB3F4715701EC631A274F4C3AA04387E4382FABDA2BA182210D7F01992182990C18041C0B8\n"
+":40900000CB152B4F00274F5465E10001030667770F188A0168210B6185100432080590080224007F0CC9883DD9EBC59A96376E0F645409003D0280943097076F929610C5CD\n"
+":409040003C03D0A7E5BB5183004E652F19F78F91FC07C64513B1AE0ED6062609706377D090FA46F042204823147CBA0C81E5D5E2E3E9B0031410F7BB48F917A8B86FC8912C\n"
+":40908000BE7FDA102366B02F2F5909E3E799E238C011B4C402D800C83DC06840F1ACD21FC751D86305C880400F058CC2400E1FCC203CDF2405339F6F4521ACF13A8092EC9A\n"
+":4090C000A010FCF16681EA6B9A16812DEB3C40D29C9320FC654843C16A0C11002E46C09E27CB278067E432121A472F095308C609C9C00302C2FF5BA2882BDB2D6335801C85\n"
+":4091000077023C24907B15A4C7D1B30BEC0E617FA1E1C4BE1CC2708F83EB0F572688085D8903C06A0C110C180681270504509670703A51ECBF13ADA0F1D3608F0138F02391\n"
+":409140009A44717626789E0C7BC8B840928482053DB85C37DD8117D38485F090A8DF20044FC02A08061D7B3CA7163A9CE3C2D388081A4908572C07025F12FC8D023BCB5CFB\n"
+":40918000C0901050C81D1014D240DBF29EC0C18704A21154163100116430BEC1037AB7044BF29F497B8760BC8C3C2C143DE78E3E9E8C106780BE88B85E945D45DE3EC3698D\n"
+":4091C0001087535E2530B9E6E261C7E8037F4FA3A2497615B955C0748C3902C270220197660176020F23C8F21781434F96548467D91B4485F46568F8B44047A0F4BA300D5C\n"
+":40920000B0107B157A4BA08D71890F2F0E0D0C037F287068501AE2C9A1E5F9A1CF3532A0D2173A46F85C0772E2772DF6BC441DBD4045036841DA244428DCC7CB5EAA7B9C4C\n"
+":409240009985603944144C6586E80041449604886E8FF11CAA51007C456D2C82177737EF2941D1890878048BD4CC7D5E2024811B71D01FE412026D3E2F09191F623E8F5262\n"
+":40928000080882997461E885043BE99842F4E330F5AE798C1D48048E05000BCC06006401304C82EC0EE1C81D3083BEBEC7A76447C334254F000FEA429235C2D2E00E21C478\n"
+":4092C00001EF48D02070A9DBE2C6580E0081AC167988B86C2906AF623F889074931EC96F2364E8F2A33205C9183C831E8B9E101FC2E4020112E048F3D8A583DEE5040408EE\n"
+":4093000041879767847903CAE050D0083DC1447063B4A6883FC0B6D31F5407500095EF93E43A8C895601DD8FD04051B7839916DE0C861B28881F2686081A6623E4CAC16075\n"
+":40934000312791E60FF5B67F0DCC01E16D2220AEBE43A63810BB1900380CDBC7912119DE630FD9304753805778786CBC77704026DD1A40793417F5B2D8DC2E165402C80270\n"
+":40938000F581D9125E44A01030F606342983D778624D79FEA87A609C418E1FA28114061BD0A46B1C9D300C5A80F1278181811EC2361387B0E94B4442270023087D5B989957\n"
+":4093C000BAA612B2E919B100BAB73593553EA47440D234E18810E1E3C26B1A30E1C1154BCC9F8897E7B3155A1DC2563D48D8B92C0278C92CCC8F6DA1A1D343066374B3A8E5\n"
+":40940000888EBD59883D1C1324B0CFB6180981E1745163A7BC56EEE751EFB4D18201E84025C22258A8EC1CE2DC190BE004D1308BA0331408D8E840FE9F09220FB20384C0E8\n"
+":409440001E04564B6023D7B3233680C73601700392E11773A511C041F12F62258452F40BDFD0C4C32ECACEA4FB1F4EE8881C5F9C242FC08227E84411CF871D915447B29732\n"
+":40948000CF4E433C80E1D2D8045B0CA028F217F8B94110340E0BFDB5F68E8CDC7CBE082187B96B102B8E8C12C3E1BBD1107A92ECC8129501E06229401E9F231DCA988C0821\n"
+":4094C000E1189210D9044A00D041F49939B1DC9B020AF4D3C200AF4D3F1B00DB067280F4C3C29AC7BA8C89D55B45D3500598EC2E006D8005F3E05601665686678C96D2A399\n"
+":40950000EB6B7440D1A82FEAE446E485D34FEB1A2331026066EE8881D350296EF123DA6EA3D34FCB6BE404EC468A96E71224902571F1EC19659D5038F703C5CC23DDEFA595\n"
+":40954000E5EE72388081E459A7A2610F2179D403F5B4397A26744E22C0443C37CD518601EBBC84C884047C31B87C187498B9F03CB79F5E584619086F9D2807BE133020133D\n"
+":40958000A6A94BB832CC80EC4FB44024BC08C93ECA584010EDC53124821EA0D6105E2100330440C3881F7A58E278920CFED6C50807BE770FB5AE4B83E78D0E16360C0107F5\n"
+":4095C000A8E9711FB2ACB3046868B0060A55182657891C882EEEAF1230911C027E0FC45D90903E292918E4820F66738CC805F089EDEE82EB71D443C1C0E2EC61A4C154BA49\n"
+":4096000094C44960EFB76E0400EC6344C104BA84AC7BE568416E8F9C9212D7A228E9CE8424D0931909BFD221D35B0BF4D6B1E0B82B82846047ACCF8C3EC10C8761E83960B3\n"
+":409640006100BADD2121ED02EC6140C4381C431034709066D8123DF6A95092C3F6A168767E410300BF0746CC946E1508D0364091E50CB4B1EAE8322913EAC612056612A842\n"
+":4096800030047ADDA4BA95248960F4603E3A6A3D107774FB267172874BF98FC1E163A1D712409604F43B05D5A746324713019A80204B02921120630C4C500D17846A014DB2\n"
+":4096C00007E106A011BDD4F243E81894004F2241D4280D0150F2261C440D610F9FBA440E124E90187008AAE4FAF048FB7F80BC60FA20AF08553D3348F4D8EA9B667174D81D\n"
+":40970000F2DE50481327A9984C07EB75D7418F46CC959B8F84A59676A8823D364A7D6EE8205F094E53A95A90DF930BA6CA16E129E7D365280216F02F6A858DCC8013F5CA4B\n"
+":40974000E174D91082FE749F330427E6B7F314248A3100472151C2419B002796CDC4160004FE9B422D48796E1422308127B58807D178E3490BB1454BC736443F821D3438A3\n"
+":409780006058F76A52D28C8CFA5448A8815263A06A32D12C18F76440F4CD5238CFC3C25207D36D2974DB3892C197B4C54AB65104BA63310E9B6843810815EBC24228106984\n"
+":4097C000F34632206B810A00129B5B708280976A0D1DEF440489C17F6FF588DC10E5EC08443F85E680F1891C019CE2F1020461D8E9A1C200D8008D21D079033C069457C9CB\n"
+":40980000801C2F031C32886E2A2024164FC492A2101B4746E2AA8174460F41C30362013F68ED8807EDAF5108BD4D1E40493B82D43E102C3047DB7DE2331B200F51E2090411\n"
+":409840005404155A574D23D4EAA808452880DDD30A846A11802137C3F25134C2F50E20388DD041D37A0B14A6889FD73E2207F18EA1C5FA179685D320107530691A42361B33\n"
+":40988000A006321564BF30C2FE9D941EDE031F78E08F91F98411E11FE5E61999F19DB081C2169D9444F248451ECE21C427244241EC7DBFF63CE010875306A5A04E23800646\n"
+":4098C000C08A40474D469073D37704068B5F09910B1DF08A3BCBB1CE60079F54143CE3E4210785B00D8254392541A254571E02CDDD98618038E9B2C2602F254EBE9B3031D1\n"
+":40990000B140ECF5169089015762171F4D99A00687C0C6DB7C7424440047B159502E82F2808DF6B7C09A40B752E088217F30E2F401A875E9BE620640343C30482070319B0B\n"
+":40994000926C0140C71173129BCBDF83A562105875DC6C8845EB7083E9B0877013298BD10DABD0F01A244CA3B7A1163064835DDE004001A24823FA23F9FDD457446A9C54F5\n"
+":4099800010095F753A0F4D44179FFFD02198256F571E99A42E00E65E9DDF1E9CF93E993A445B0BFA6B41C3594C0E3282F623E3F660696417A34CFC4C135E5339101EE39124\n"
+":4099C00003C73E9C891E074C5E1F9E2DBAA4E1048F02E287AB55A4146745A431A5A5E528F2D18E0901E9FC943ABA04CDE40265F93C34C8221BA95C08DA25FADDB4FCD76890\n"
+":409A0000349C48FDBBF8FA57C86300D41C0BA21BAB9C903450F021108E1E8F8B3EAE803337B1A9C5CCCA43E09D7167B6E0498EAAB91257A95AC7509024D83A0274DC991AA7\n"
+":409A400004E706CB2257666B1F846046DD802278925842005FE0675905FCD84932E12EC702E81399122E272336A60201440408B4F64159F4DD9131300C501000EB00A908ED\n"
+":409A8000819468109D8B5C6201A2421022A841D4A668F118A1EA52D541A4C550861D107130D426623F11E0583E0702A4203E064DC1D35A655C435307EEB5C2A99476F5125D\n"
+":409AC000D24B97888D0880010810BFAF61882E0BD53B67EC406F07D308C24B80FA36C163885708B5EB5B02D0F325E79F52EE8402D3C11451787DD8A308701ACD1173C56B03\n"
+":409B00006362B03F82FF8587058018DDE91C412F4611B413C69224E90C0B823E0A113014C33B4F83782FEA54621B833E13723181E2CCB269820CEE63CA670209FA6A54492D\n"
+":409B4000602A70027813EE2D61D5280E2430008B71187534422344A0284F4074100F087D7CB0801BDAD97B7C3C7AA810ABA43B545C400B25205B80F6CF1643E1E900676378\n"
+":409B800036282107475BBE40F0CC65999C3C5E4A5592270703CA105BCEBF837ECC107B5180887342614A417AE5A44B84FE108439B04B82081CBD30409F49C009E031845810\n"
+":409BC000DE03B1A74882F2D4B160E00A5232E0E7BF037ED8C63800E010306E6828F47ABEB4414F0FC4100750A600C5969E5CA5847A00742463531C04A2E0E2AA53228F203A\n"
+":409C000070A835BDD9AC580419E12688E44E216D81DA1D840E0B322792C44C45416A136CACC3873009711C680CB76D31DC75C72164440C2E455225E0C472203B4A58F0D41F\n"
+":409C40008D996013AB43D1359581002A43B500841B0A20C2BBCFD56F26C7931E0BC24BC5D493C5F00B1A028DD90B0140958654304AAF04CC8E014203C0AAEF8283B19D8CE2\n"
+":409C8000FAB5A174DC721D3718581003A6E350ED2841037A6E3CBCFABE384E40F3E02203E242B11CAEBE10804EE0412211F4DC996FA6A569503C80F21C75F1B5B0D99C0FAF\n"
+":409CC000EEC7CB1DA0AC7608C43B0748C2E3840234CE61C470EAF7722403F08C46E13ED37C489602FF5294A0CDCB01D4A10210E10D1EA9CA480140B1E9C61336D1E9B98416\n"
+":409D000018B458EED3488100095E17F7EB82B4A5529FB67C07003880067171D53665D4184211F18A433FCE020446E268C2418F021102138F1E08BA102802BC186F901F1CEF\n"
+":409D40009E104BB72BA3DA39B3B7D828754D4A60211F39EC890A2E62BF9F4C491063D4D1C44287BE1964205F3EF04D12D476F856F4C810AC0E3AA20BC55543E84021E04149\n"
+":409D800062247C1F2A39FCC26B959BB8710324CA890E041720279DDF040E1E0391E70648093D33F45D8DFC45B013D42B034D88A34787CC910E031B5A06D2D8220487094B07\n"
+":409DC000AF630E4801EAA0B2343D70703D2D869771B9890E02FBE474BA5ABD0DC908407881E96B640BC1FC0FEBD723EA7073094090508D1FCAF1D4E9046C2025C7988CC8F2\n"
+":409E0000C1EBA042D69588024B7C0006250E4BE9305D14DD8F5C58AB4C06EA6A61F10A68FA1A78BA718444A488154B8042E9B1E1C3B804179D960C02912224A8096A1E471F\n"
+":409E4000A478606C703A00583C1CBD4DB09884A1783431DF27831A016F958A44808E440DF30369B236A216CAC82EEB9C741A03900D180D09F00B2A017EDF24A628D0E2D1DD\n"
+":409E8000A40B7737210F05A120281203E0140FB0601AC2F6E3122550318D2040829818F1B7794E404F421029E03141F70CD983B7C591B1EA8181034CB241001C910BF6DCD3\n"
+":409EC000C303C1E8403484735441C8FE744C484C60262C181100717654801C73226B06A0B815D4C727D73548088E005AD0CF1C61EB800AAE0381217F4E511070A606175613\n"
+":409F00001726B02D01FD978A5D39443EA6F730182B600F47700810B0D20C0D1063A71C846243AF45C5AEA60D3018D5A1088B48F052F4C0F237D554637FBC990007732A8929\n"
+":409F4000A1EA4D513441E2B4CAD0F0086A060AD3923DC88A2E3E04379675744434602E400D2B11DC3D887FEB9964F01721ADCE2CAEA2C8842CAEC72440038708E44816F6B6\n"
+":409F8000F8591349657922C6FB785D394C8803EEA8C36760E41E9CA25C145F6017471381C26F000569A9C4FACCD9B0229D625C6139A212255183510044D57A20297B51882D\n"
+":409FC00001A2123920C2011AA0E6C36A3E093A9B9F80D2076BC0082102BD407E174BEC9AF23574ED02C77B110ECF683064690335EC20CA42B0266264C5BD98F246873832A8\n"
+":40A000009F46E58879DAFBE2087532917C3CDC5EC61048050F67C2AA443A73390AA042A38C4CA90548247A73690A4465A920039A45AEEE3C25AF61FD91AA5AFC2A064519DF\n"
+":40A040004069968590C45C7A6ED84AA080AA004AA198D22C482E15463D86A64021C34B90AE706705A81AA56762002039874A425310286AAF6267CF04460E1AC4F61590F6B5\n"
+":40A08000C6C49403D81E42EEB8A5D86F03E32DD16085F84DB448ECC78123BB10252268700A930282EB0A224B818392880822CF4801677226B117D881481EE0C783F4970448\n"
+":40A0C00041D0EC4714C62EC40950095435980F4C8096868301B903E341F1FB2311B9D055F6336A3D8810D39BDB9BFA256B00A8D0160DAEC9501600251A893EC40979202496\n"
+":40A100000EA9145802C4E71600A5DED59C9CFB022C82F43B1021D1357D41BD0216073121473670FB10257F821FC67D42D9F06B3908C05113D8812212AF06CC826684232094\n"
+":40A14000B5414BF7409BF7C0233E167D3A260441D4303308B1D881060084A5628F26CB208BC10E08002120F1D8810D766B5954B078A98C7BDA1C4D529ECD61BB3C09DE5D06\n"
+":40A1800005439074568826814BF0DF111A4527770A171F5022D73D28411F10148D2B0C51918D7001126801F8492042321C7930878EF4E71A05017FB3B60583607AAB402610\n"
+":40A1C0008BA1207B03C863838B10931E91F01AA842AE43D1D0C24210D546043D5900E635559A51006D14889B660B4300DA23141427397D1010010E66C0A6C1DC21C66D57C3\n"
+":40A200004A186A80D520FD9EAD35D83E564712AED808EF9603DEE4A268F66DA8823A5ED133D10104902C68060E9F64C391AE3882E2E785DE07278C786EA8FB6E7C426E3288\n"
+":40A24000DA217F10B71398AD0838AC28841C31FCCE63434D8847B111DDEAC5DBB7281C00170F4433910ABD1E0BD224178A8F0BCD0705EA3E31EF2161E17EA34D0063D8FF35\n"
+":40A28000081EF868307666B2040613405C4005EF77A23D2CC03D8BFC566A0648961AB35A3E73722F1E53086A077C24022CD8984540208A51D621222B85FB92C22C7A1614BA\n"
+":40A2C0004D51148D00BCC53E60821DA4762C06A881033CD91EE2FE1B3B9FB54DC71D8007E7804FDCFCA20113A0111A13628E1094D00F0DAF1383CF62B521AFE023443BB5A0\n"
+":40A300001AF619171F851F0680201A0100528E2D00B1905A087DCCF06039E217FAA60901D82FBDA802440223A43EF2A2D11AC15764058896B66803F2B107CDA3D36075106A\n"
+":40A3400006D3AA8049040CC0D16A77441903EF7F0281C017EEC4210789DEDDB1120083F3063080411F06133F03C608121088DF09A6886A5680DDB6EA47F97FE27C01EC6D5D\n"
+":40A380003101C510BC00F37852166C118144283B1BDF082282366E20A068B36284E79E3B87B1BA84895C218D22194432CA9018D8F538E8953E117242D0400058BD1201505E\n"
+":40A3C000AA743DB5E9242968091A501DD886CD0080E9D196C8877874383A1C0C4E85F0944F04D0688AA5D91E40763969913E6C201F4E1788DF62E600B3A94C0E0BAADD0613\n"
+":40A40000C053F42FEBD8A50A6AEC1112C5CF2C07CD8B9579280C59BA41067CAFC021D3FA2058D4CF3B809EC05255440D069411A83C4140C847780F2B2F486ECB527B0B16CC\n"
+":40A44000910DA5DB16C0B00A75441A03442B163CBEC0C062021F2CAE9821A1442B1218D8A8C78E0788A58D04010A9AB1721A7B613BAC5A2772E1D483AD475B12A407B16082\n"
+":40A4800075A5F15FDA62B51644E70309651EA0E847BFE7678C9E17B9548B4F1C27001C5D030501B21181006F6C9C09BA815D0C21201A80300920DA038A2504A5E807C5B46F\n"
+":40A4C00004D1ED953111CD633CDA3B0D5358DB28F0158602A42C02553A1DD0BE3D19EF314160A062D78050C62580F44F2447312A213C0D006E326D8A37DB24019C3594809D\n"
+":40A50000164123D90D8260AFA40924A9091A258DDE00448CFE956A1014D02DAE7178D12B7B21B9002466722AC0B29A9C200190217F04182E00FB26B14047044709127B8301\n"
+":40A540009E279A47B77B8C0502816088401305819C7021B46D246D0327F974780686894181A1525923619134D89051A4C8935118C0917E8215818CFD042BA2F590FEE8B750\n"
+":40A58000643D28787857B21BFB21C167019D7D20407D52888C2050FCA381A0463561856010AB53C4049C48EEEFA62811DD5ADC78F9C0C128CF22E18143C2AEA22B12A2AD54\n"
+":40A5C000B68303631B069889330089B6A02C370184F52C0D413E8318CA00388B105CB902BAEB246D482528160796C0B8C140CC3F024FA52230BA380F22289EC0DAE0FC9942\n"
+":40A600006A90E525730B87830348E4840F670D8E0712EF82D1C0B8A11D81B51ECA9148A54AA4043BD806C8171A01100C7AF5121955080DE39021B18D17A280C8721C3BE9F3\n"
+":40A6400028BCE4B024604AC6D8F63DF41E3EA2212F3937915C03FA5328871F3B529CD41E10DB1206BC047E2E0C1F1F3121E073220B041F66009052010E000CF60680283006\n"
+":40A680008B3D751088160F20088847F8C5E52F242DEC7D9538830170F8A36F020BBB73D442DDA41040728304B298249611850C16805AA80005CA3CDD58A1CA6A9CC04965DB\n"
+":40A6C000843009509C9501CD1392E076CE1348E148E16DC11305BC000357081BAD385B2A2FBA44FE0BBB28B84D6ED03711DFD64C6239835E57962B611945C7038C0E63E197\n"
+":40A70000D523340D10243E05F8DF689AC63E79888066B99E3D8DFEA615236803AF32E43C090F65790E50300259055303DE8BC801A654FC8FB5EFE5C4073A42EEC9A0408A5A\n"
+":40A740000B98358B3B67178BA587A7D392B67A00482D7B7C0A02F0DC3D12365D2340B43C088344B4ECA3F54A948D259A057F6653095AA005B0289465ACD02AADA0251A4494\n"
+":40A78000F30291FA097605FB82116681376D1125C8240D526AD8C6055B4912D53D8A9C44D34890B6981AA4A47236D440AE4E3843FF76278DB540885C29978040381F108FB6\n"
+":40A7C000F88F8C015503FE161E13408434474B6CBC881845550223701C6721AB2B3B8180F133501DADB4AFC20886680ED81DC3CEC3D24ED57200704C8F82CB0C5B236DBC0F\n"
+":40A80000A14880B63B0226B0CF89284675BBF7C3AF6284102D72BC0ABB070C408008EC10886BCC48DA012250ECA5C4C50B74A9E31E72C17A1F0C018D13404503826513C048\n"
+":40A840006CD9A9641EC4ACE8BCA41FB302037B748EDC182C1B8BA46BAC4AC456B21D2FBF6E56BF7EC423673D003AD8A989F94014250BBDD9C89B2039716F44478510C8381B\n"
+":40A8800072181B97F822662200EF3483DC005384B8C0736E084DE48E1570050160E76777CE201CEA64073B6084EFB818A104F146E080340ECC0022762E1D2691D2A3A58EC8\n"
+":40A8C00012D2B850BCCD902141A0729A3F122B0F6601A802122177C17EC66A9B646ECE1A44B803EED265C03098290CC190030601306C1002013B5843830C0D135C111AC084\n"
+":40A900006003013980D5DE89A606094A4159A2679A068DF7A67547226621840018DB94041D344CC362D1006FF88EC0415348C6F37CF882B8358881014820D4F1374D131A36\n"
+":40A94000CB681707278F1590F1C5748078358CC14C033C6CBC801637226A96446F94B787B7C9C4BCE3AC46C7800E470AB411604826008A0C00B4487DDD223F08888EFC30BB\n"
+":40A98000380403D302046B1604B02BE1C161104B8212CCE894B8C70681017D8830CAD5302442A2A89440590548D106B0A28D94878E668885C415CB603220840520382E0079\n"
+":40A9C000FB34D06641A9502B4E640099E87071916287B221081500C310B8C00A38053080A02CC403805F929C855C19286890AAE01842C472D82E44D023B05F410030605C80\n"
+":40AA000018206003026C14056B12C4A386E6E01DDCC023B512D58014314BC0C12947106BC3EFC804E17D7F01AA3B1B1DADCA5EBEA01CBD01104FF21CD8078FF37CC1204DD2\n"
+":40AA400080F0FF3BAA240FF37360C018623AD2364C120A144E948D7F4A0311AD9D012019066C0805C11FE94CD2ED2E611022130192021B785E3C7B5AF04020851D52D1F1FD\n"
+":40AA8000E172F01E911FE364EC26218241A469A8C14866B34145F1824228CE517880311A8E91EA2EB1C23006505FC39C47C6F3E207062078F0770E1E04C7107C8BDAFE48A2\n"
+":40AAC0002733C133AC14DDF947C97B232310854F8FCD0F69A490C20CFB86C8B845B954101B2018EDD52B920A100380440507D0E43D19DEAD09193011FC15508D30AC7F3F45\n"
+":40AB00003CE2044599CC5998E59E8D744B33B0B3334B303B609E114F55BA241ECE7026277E0A1026416CE7A5AA701048612E58D0698FABAB04A2F25861712CF91842EF40F2\n"
+":40AB40004B260480C1776022130389166C0507F9386E9FFDA70C20717A04793E647C9F26400FC4B8E2278F0110126705D8D648062E008F4D8D083E3B82013F84D04803E257\n"
+":40AB80008FE5F12B988823F19E3C98B3814C02116A080C92CC52106C2EF1E0B1DC14640288687A31007946316EEBC84500A1BD63203FF9EA692B7B0801C516886CE5DCC8B8\n"
+":40ABC000600C2F5B54212E1F36C211FFE80F0420C443AAE1002AE440D1C48BBF3C27E11B7B4F8C87D2F75FA244900A3D85E3C0383AF802F4CB2015031C601EB82AB91EDFDD\n"
+":40AC000003530F0B681E5CDA4018E4340F427FB0ED121E445A3E81FC79A80C49C6360DFB65E900B8A0F4A6C9E4B529D9DD726E80258758B68FC289022B8E054E74888ADE21\n"
+":40AC4000FE7E1BDEC02CCBD210AB2AC44513FCAB3C2D2A06BF8DD80CFA2C40EE40C02C6B2F84C11E831DFC4D2EB8261A0E1EFD5E1E07968172040EC186CC242259EC239B36\n"
+":40AC8000206C322249EC04F6A0491CA7259D80F335CE9010ED35FACFA08E1207314CB8C9D886B9820805DEDD9E50460B90363855E8F798A891DF0A9C0857E825A2EB43C1AC\n"
+":40ACC000037754F22D7818E096A051B026751B708027F84A6C075E75D323FC23AF6121D0068D821E8F08247F98FE0A77121CC1080FF03CD8F876144FF0725E52D2960DF07F\n"
+":40AD0000C017CB4E5200B360C1028029EFDAB10F42EF051722071A4171007F9C3E19512EA71C1C10D04892BD65D43F12951FA12004B1F62030CD004A8487F13D71F01CD9A0\n"
+":40AD400093C4C1C223F780111B9576060007E2723104404EB63A1C69902781F74E892A381B1DD47025C9167F1266C1066C9587F1DAC1406F789E984FE3AC063767502B4C2F\n"
+":40AD80002EA96B2A603E616B1D995440EF7E938CD80401B21A20721B15100501FC7120421B2701FC70D251014FE37CD8290D99E00DE3603A364003FB6CA618311FEE1716FC\n"
+":40ADC00047D401850F88100D9A1E0479FC3D7B69504423F878831110FE1DCD1224D811901D7DAFF4218172471FC399A2439B0251FC391B026439DB3A2DD60271FC371B1E7E\n"
+":40AE0000FF621030133F86C34482360523F86BF6D3008A87F0D26C0AD3408D0688F86C0B07F0CD4742C1E20D1FC324388B880C6688F66C0BC7F0C3062301FC301A23A20339\n"
+":40AE400011FC2F1B03249845D6066485B346E5F01A18168D11C4D81A8FE160D81B28398AC6C0DD1A22A9B0384188A6688DEC0E47F0A468CF403A1FC281B01844889EC0EC40\n"
+":40AE80006C98A5C8087F09A6C0F1E038D2604B360863666D0294D8220D91C10293BBB2840D254333A48325824B2E888946C779BF16042AA110B102750429B2601FC4DD79E2\n"
+":40AEC000890A7F143EB30693F6A4C4E34097412F35092C6C1306CD4001286C1330C35701F11758B048D4F8C900903607A60072E40C3F832F25D1C81F590885EA15240C7B0B\n"
+":40AF00006228488C22247801183FCB8E7190181960D80EA16110E6C0C86DFA065F05D9C3663B8506A88191CA9B0CFC2054791BE36120B6201A01D01E27031F0AD61B1E26B9\n"
+":40AF4000CD19A42B5002E017C07D621000E70E899844DD7190B20760CB407E0BBE13FD1284FE03825EEFE043501E5ED4121E22D840D8B07B93910406920A2138208D746136\n"
+":40AF8000301B34DDB741823131B4003607D0A3D901C2107C16F263A860688383A9A2508166C02D3F880CD6D86C33F81FA7B1B0451B2069FC28EE06E88CF6AA4B01C0DC78C9\n"
+":40AFC0002376FB1C24964B90F1960900047E17E423FC10F8FDAA8281C191CA20A1047E9108A21823CA23083A082E5C4303A1011B4691EC00C551600B9DDAA4C1BB784D53A2\n"
+":40B00000B59C0BA8663D115A0095A103268F5E868B0C657897A61CC7598A3E51861044AD01FB008441F35CE6030CEED1491638DB591B5DA16C26DF68B4A66B1C3D640C3060\n"
+":40B04000E2CC600107B9026FC3AA6690084C83B5A910BC067C3236237F616F1E166300A5E901A29033E6F0099AD30013C2D22048062ADADC72728C0A3BA8D064250992BEF5\n"
+":40B080009020FE47C3C5C65C00C3D820686CCE026896F7FCA592A025F6422A0041B522268BB02C1E064204C023E42EF26A9204D4207BCB48713C108CB407034130888170DA\n"
+":40B0C0006B1F092340A7C41E7DA0AA99E01A9A255627D549E4BB4C89020D0291B130D0774134A251813989EDE408DC84B74AA50164D223D976990245E2809A8225D16CC02C\n"
+":40B10000414108A209E6425A0189A03CA00035F8794C470A5C61028E31231C713D3C8F609A4E63F20350126D55120C017EE7AE1C4F2A0CE9DD69155880121D2389D8C54569\n"
+":40B14000631102D2308600B8D0C6B826E139114B27D1834049CCC72A1C0F425E42EB05320071FD4351110090F9488EC85D123313A3A4029074F0C87EFDFBF7EFDFA01574E7\n"
+":40B180002B7876C0F02F1154A21F848CB12F081030238128B66979ED0FA40FC500043D331CE43017688EA367F0CC3246BAC02E100D03649009CD5366E022C23F0CE3E283D0\n"
+":40B1C0004CD9622858004176076EF653136803EB0F222B7BDBB0591C098358D5EBB951B76801B6F022E80CB8800D734BE22171B82C40923ADC626863552362DC226919C679\n"
+":40B20000D806DFC598A5C4C1E7CAE2E20B4AC6348DA3C6582041D07B49533150005900A040DCB061C9EED0BB693500849834FD6590E6043406960E3AB35800E00D40815B91\n"
+":40B24000BFE91124177758509AA535C5CF220614562D260DB60963489FF8B6807CC0C6371614D80C138A20610563D449903B61A616C06287B2A510038428403548423401C5\n"
+":40B28000CED679320462B8C418235127401659D9446EB3DCD46238B043A3186D8EE97C07623182329AC3E90C101AE39F6A4C8802688FD711B91623638196895BDD95C25A1C\n"
+":40B2C0009C2C91A02653714B8447607220A761234247430918C10ECD21B08261C9C6E2F062307B310C6E23119556444D1688C78842688B970931140E3680872157B468E468\n"
+":40B30000E0721514683058A43DE50C800A4685DE1D62442ECECE54D111CD612AE0D110D6CD20C8D00D8B2006DFA05500280824053B00D592E80A4058ED507202C069DD1088\n"
+":40B34000E80D1194BB4B4120857D8060A0118148FD90096FD71E8045F4616A0209D4042542E18156DBC2592888624001E88591B7021CBA18802D07A0811F09AF20C791706E\n"
+":40B380008BB90207AA6CC60841346DD047875F5F20C084122B200000030003B0000000004206000038000008A4001FBF7EFDFBF463F6111E043A57D658D0D78EE212800639\n"
+":40B3C0009880B0293900C501F6E23B8E9F02413DA6A24210141100CF3D56E49FE4F8BF84BD066FF2024407207715E317F720320BE174DB24A8521175E2F7AE302DAA0D20E0\n"
+":40B40000277174C376942DCF5CC251CC2CDC858C4F18F4DA521B040190601886E0040C5A501B6009DCB38426DC63D4DCAFF4DB04F608F24411097D7DA08301896908877B7E\n"
+":40B44000A6100FC0D604420C11CA092EC7262B0650AB855070530F98ED90D29D901090089E5D205921742398090189EDB58200488479D90142176B81136210488CC94C0440\n"
+":40B48000CA41428014869188F41FD1629EB0F120153CED38A28BC795C400873461E5F7EFDFBF7EFDD898378DE35EED45A89BA8A19ADE01CB76E03DB678400ADE3D8CAAC20F\n"
+":40B4C000E00374C0402ECADD2EAD421EA1B23EB56A2C4AA459866C9CC3374B2316E40D3A84431A43218C20D917A8250D36B89B003725C6F7268477260791CBE4DF72264FDA\n"
+":40B5000051F461AEE6F54360C61C0721C064188643C0C90E4320EE1C86E1886830C2E21C06084290C43A86C1A0641C862338EE3D6E72663586FB0790C9B20E4305098CF69F\n"
+":40B540000FE9186639DCDC9E57DC1E56DBFE0B6FC7FA8BD6DCE7AEDCEAD6C41EA6DE48ECD07B7E410CFBA0B18A622EDDD08CC230BA0A9204020D3C1D6CE9153319823662CA\n"
+":40B58000442D8F454D43D67B18A48EBB5FC4841A918C86FDBCA1008367B420F020D88B0E4CD8D032ECAB6726FB2F75684791B8165802857EBA1491303A6648F3FA5B1BAE87\n"
+":40B5C0005B197B3B1682DA9FC60354852A828D80A6400D8F40443D4F908E832843A9A0F97DD642F621002096B6304200454420049884009B1F18D49361002AA21002CC42FC\n"
+":40B60000005D88400C31080196210034C42006D88400E310801D621003CC42007D9040C42008588401131080236210048C420095884013310802763B8A09B5C02C09B08072\n"
+":40B640002A510802B6210058C4200B5884017310802F6210060C4200C588401931080336210068C4200D588401B31080376210070C4200E588401D310803B6210078C42069\n"
+":40B680000F588401F310832A44750A15B6D55EDBB66226A5287561B857D256E75EE1FB0E7145089993822307314E11D00492361AAFB8B8671B9190158431376DEDB10761F9\n"
+":40B6C000D41DD9AB0A060C6C24D41EEB1551F36208D47C0D151A03406400756DB08E1CB930432F404DC8A7BDAC0C90048B4996F3DF2348C4396E9D686EE6F437EE850AEDBA\n"
+":40B70000E8E2348C239C32436EDB4C50B88C23C28EC59D43A8C686F4574CDD6414F16B9D346A7336376463BEA004914EE5648431584514A8AE6228F1BB7C4F07A018430C97\n"
+":40B74000548326419840800006000008000100020300070C00000000FFFFA1EC3800000CFC244004C11147E8BCD21E8411BA10C720080628F1830841E1B3018420C1484071\n"
+":40B78000513C00142784A141454C267EE3827E907D2B6673795A0C4F48213B278765A8840A41032081902038018186A5E0CD4D0B2C863A8332D6139C390549800D004070AE\n"
+":40B7C0000303356706E12C61965810DCE81094A8057EAD2EA8410AAB9840228CA66B0A841FA01064019D1146CB10C18D1418392623AB8002A14C140AC17B9521C01807906C\n"
+":40B800000B18838122022621006480C178F30EC0705192964D0034B2288C200C32EF7C32A6E41870C0F18433480162A8CCD483324228EC100304219FCA2189C003902C0883\n"
+":40B84000025034603E639C86C303B861ABE30FC2C110284FAB7AE4468430084C19943A84DC5C006520205E101801408C9100305D105400E0408860081062130F204E8B8008\n"
+":40B8800029822C1C01616C83500606021180342D11AC01C640F4B11080921694022218646012020183009880071877D5A0B80542B160A0160AF3E20170A228280604109A48\n"
+":40B8C000C03223458601A0B069300D843229807022924C03A1162100F043225403E14698202010828A808442020C04403270404616459501208A17D80946D518404C24C604\n"
+":40B900001501388218980A14911148809810150C0A9040561927040583FCB75016840AC83605C102A41017841844060109446210EA410190442E94066112822034087204CD\n"
+":40B9400006A10A6C406C206B2101B882844315B046203910141101D08010D407623444603C1750880F4438BCA03E0862A301FA6844805220881081810814514408618026F1\n"
+":40B9800050220801558114400E0C08C20250811C2649102404530D40921162102504C90204B4A11261489A410AC09C1B0A8604F0D84630B3A401CE0C17D451029088844031\n"
+":40B9C000A62F07850ECA5C1702A889B3F1B056101510815C014D8816043012A05900047302D250896C40004A05C55C225D008A25E1103E302F8AA21981812844C221C7A583\n"
+":40BA000003128422631863CA81914A11328BF51332D10899C0889CA0683234853B3C206A08534206B18153881B05244206D1812040DC42BB10378608840E016E8620710B36\n"
+":40BA4000568040E45239995E88052B81D4812EC0EC4442077312C40F0142D4081E440DA1103D083513D8808440F82A6C1081F44188AA07E1610881FC41C6187C001476801C\n"
+":40BA800030F80238A1100108CB3E1B17D3838811680418028ECA9C3600C332DD06C01C30904A0080C5490D8048425105010331802C3212CC01810AC186C03420976A00E01E\n"
+":40BAC000812C401E1007E50080CCAA036022B3020C048E2C04C41D4E1B0141815306C05568C4180B1C580B800321403064190833A201A4E0886D5F88301C5AD10603A716EC\n"
+":40BB00002E000A28831722201F081638403E10AD28807DE3D1E96C3E118C894202438B0255AE10604CB4C20C09D6BC418141C58149C581528E222B290B0C85A642E3217968\n"
+":40BB400090C0C86264323219990D0C86A6436321B990E0C872643A321D990F146111E89FB800D8608A500F87E21ADF061F100A21F104C43E211887C432AF2F10F888833255\n"
+":40BB800029408C6047302418124C094604B302618134C09C604F302818144C0A46053302A18154C0AC6057302C18164C0B4A1265B001671360BC2A8066C3E3001EB789877F\n"
+":40BBC000C610EF4F503101C02140C63AAA2503200F03D40CA03C4A606600F2C40CE1103B50340123C1862CB80E5C182182F7035AB0513600508D40DA3E0AA606E0A1724926\n"
+":40BC0000B06F0A002A6188D4416046406E84446C510F8F01068A207900200A81EC0180EC0FAA1089F90889FCA3C475C6DAA7C476442C6C312D02334130C4B60500A586252A\n"
+":40BC4000C04809AC312E81CB904C312F08602D300C049C1000C060B258601E5B64B601815088E1021700210990C010480A700C0169622220017AC9B0240203FA808D10880C\n"
+":40BC8000940607EA0260213C1B0270197249861ACC219916844B0611B7846910FF13880072C31081250F4B570DD2A7822200C0F231E482E41349C0BA07F9DEAF987D227B61\n"
+":40BCC00061F8040084A9E2491B2C987E03316693EB1151A2061F8154A100FC0C00EC1061F83C00044987E0D0037E0987E0A481111007AC4360180041E5004803A286C3005D\n"
+":40BD0000A822E00B46220800B5386C080A54A110C01A0081C4EC780172855E005D4710068FF3EE1103F6780265BA94870EC5BF1C28005800401F115D101004821091211139\n"
+":40BD40005D2CDC20344080673240328264E0C2064041991019401F08C91600848284809E84DB101068640648033A9405282A48082524041A92032803E10682C0189058908F\n"
+":40BD800013D0A242020D8C80C900677280E505C90104E48083724065007DA7AC2C02090609013C59442020E0C80C900679281250649013C59C42020E4C80C9007C212458E4\n"
+":40BDC00005120D12020A89D3CFCC60440B07B240B2836578B440581D9288163D2FA82C03097A0EA058F16740B03C25102C1F49034A0E95E2CEE1607A4A2058F0D220B00EE1\n"
+":40BE0000241E285C579F9E85888160FE481E507CA17943F2A20AAA8580812F41A50809E20A41013D09842034410049044A1092020C4A2092036C1A16C8A85B222A79FBD867\n"
+":40BE4000454310F032054CCC713C034E08244506C12F2127A5C509000000000006000008000100100300454000000000000144883800005B403405234453E0C64229C1A21D\n"
+":40BE80002A7432208A8690A9C92B060C0554855F0D0408AB0A81A42B4188ACA42BA85765E8FD8160585216542CFA1C60459DE9B045987440444D216A1445A8343B2FE461B8\n"
+":40BEC000405B485B47659A8FA7C68608008341089440944D21721445C83445D485D642F285E642FA85FF427608BF0A81A5E903713406083446148616250816688C2818B851\n"
+":40BF00008D288C4E5D96B22C0C6A5E4B111606452195432B21994333219D433B21A1434321A5434AE080021D418861E06A73694000747B43081606162BF0449162C640040E\n"
+":40BF40001488FA0E7040112C2447D07202008A46420008B58E1C424E13D222D6F8703CF2A44011737EA61F28E00C207370A16058446022141624613713D41E42C619AA630B\n"
+":40BF8000AF61058D5B1CB0762232FAA69846639191A43CF43001B035798C2046A293D0BEC6008DBA3181621046FA04238F174E108E483A284100474F32DF8B14407C53ABBE\n"
+":40BFC0002CF3EC711DA4423B929C0EAEC011E31F94849901723C8D1D12D07899626C1B8A0581EB9329084992EC23EE1A21F0ACF4803D4D913E83F420047EC6A923F6F620F2\n"
+":40C000002124100023FD1E10947844803415E75B812268B4E0E810048BF3350144091744048D95091DE66B62A043D44953E8410200490C917109F6E8C12438466084F9050B\n"
+":40C04000F2496AE064270A21071F10B19513249900D63589253AFF607C1D1E3CA3987A26D0E100E44A7C1630FDCB1E779F12777F4C109FC399224EF99B5888C8413D12A140\n"
+":40C08000024F008D784A18589217AA9E440E2E208310E470DC920B840E5786A76AE709E848031A86D914C023079EEAA0782014881E79A290B0B9017807B1781E904411C467\n"
+":40C0C0001202CDA08B7F8E9601AF032E11E1D23103BEF497799C200798C0B1403B135C94248760A0ED024D4E9F40108C01224041D410EAC4C2E6B505CD15C581E402E97BF2\n"
+":40C10000A1108D43723870F541481278C7AC811EB8E41E81B220A530009D0BB7F7C440815A8707534D0FA21C4489017B7DB44CE358D060A021B8B8188121505DC14FC4D0CB\n"
+":40C140003347D08880058672FFBAF54B7D6F43BCF1079E9B0F16EB100BD83265C095C7A9A60A210E73925E59FA1E3BAC234F1E1043ACDD87CB2522010BC0508411841D45C6\n"
+":40C18000F53D7BEA3E9D851203BB3C8BBB24880E00816F5D6309A25D17028162061A25C96200705D844C20B820363C175EA169D261E2481727675E719700E91007C136442F\n"
+":40C1C0007903A689604C9964C8585F74CCA8FAAB7C409043B21D8801034EAF52738803EB1E73DF6108A605BD75E887AD62D026A1CAA980D628FBA328420E95BC28F44A9E96\n"
+":40C20000DC7F2607A4FBBB08C22440D1BA1CBA71C44C21F4B6188BAEEEBB4A524CFA854048060932643F2E7BBAC9101FBA1DE9C3D6AA875E61C11DD5F01451704291F04352\n"
+":40C2400000F883107C051E5C2F184B1F0A278F3F6A2E678E260B078202074314978C900415E964D2E94782ECD263E830844A243937A8B1E06921203826A97420C8F2DE4152\n"
+":40C280001C3C8374413F4E7598883007034069CFC6C441F1FBB083411080180B362100D3A3630485107CFAFE20C043D404025CF76F38D140F31F590420700DE02C53EDC6D9\n"
+":40C2C000612A49204D036FC14F45342E6E291E9E77D3113CBF1406F287AE1BCA6629912B278829D9396364B010BC927A3E565910D417ED34B33D3B9734784198E0418ED0B2\n"
+":40C30000BB2E5E622138181954F173FC720A64E99B4004999F4C9094940064FA0D70BA6CDC7D33B8210F9E8D8C3F3FFC13BE45C89DD25CC20B00A401105075C2B08203EFB6\n"
+":40C340007A2B9F4A6C08A610B0177821D4416F19E41093C42947B960479BE9092FE1B0111F82E083AC1544B2ACE10BC81300660777F0211BA24BA1EE44A2E304E8017600A9\n"
+":40C380003183D671E8028028E75B68779D81325C00CC0443026112F124C777C6101A0B572A068F982907CF1FE81D00297030F5E5111528759D09701FE1178D9BCD400BEBBE\n"
+":40C3C000CA322C028EAD644474B7C17A19094E66A066D2466279DF81726B62F380017470E17777B25D56545E7B384BBBC087BCD18FD8314406F63CE1048070CC7D91FDA829\n"
+":40C40000F25CE924B91EB1F79EF11C4A3E292622E0E2F0F0B570C511038D137F8888901C4305DE5CA8207F7CFD401736C7606B9A9E09B43B033C442CBCF6542079908711FC\n"
+":40C440000E4B8886113C568FE3078F45C702401A641F40869000418423D0ABDE7F43DD126241F8D00047815392BB892C0B141CE9E048002C56AAD132BBCFED1326A4C4025A\n"
+":40C48000E901C2EABB22E69F620F79FDF4420348C7E9F1E2EF0452344C5F1B6E14299884CA1E3425267A2D74BC6C785C44E0A6112FE247D3B2C26897DC053CB9D49152E32C\n"
+":40C4C00002C0117F9CC988227809DDE74222EA568F1EF39D11F10F43000977DE742561B0F534E99A058F5FE1B41A2656A8FC65D7FA8CF0676271E63347C19E8C7F5025813F\n"
+":40C500000A9531FFCF0A427E548A721464044F15F522875DF89712062A2845C1CE79105D05425D08403DA56A3C0F3C608C3510023E419E5847E08E3548EE0F885D084A9751\n"
+":40C540008B3313E99D413D060E84272E841E110A97A5D0832221D3043A104C440A6298F7494B952A1D2E0F2FDB4FA067C6930D24006CD02CBD73D043A77A0119D1DA53E75C\n"
+":40C58000E0402125812A446272882C1102223524101D6791A495D9000100D79E079F08881538B9C5F0F49FC08F1E5FA11084141F8401F41C2F43EF57298DC0C1E2F771F5E8\n"
+":40C5C00002D0941E501D43C6FB885AE8098040703CAEBC00951ECF4E208CA40538F2508223A855BEFB8816058156B21EEF5F1EA59520206EBA3C89E0CFBD800B86E5885547\n"
+":40C600003194D41E9879105C200409E0D3CD72E220461824A360621F7C208A7C3CA045E27837ECB8D1901FA9F447D7A3460209B1C46B87BBFCA093FD52FC20F14E501E000F\n"
+":40C64000C73A67234439020069D0BBD11C7ADF70ADBF0614A0887F2911172A381E84841003A8CD08A7080D50C09D0009D08BC1470443F7A3C181E4D49089D087B8AC47C7DE\n"
+":40C680007A63DC4CC8713C81B24A006A3424789741600A80447D00BD5DB645B807E61C62E004A208301780804F814B089E0D7B3978493EE5CA1E22A82051160083FDEA5858\n"
+":40C6C0005DEA20860B61F25AF107982E90EF51630691E9EBC2E7BEC41C05D181EBC921642C841320FF3F07D0C19EBD4A2EBFD06B9FEC25D20583CD578C18B898C0F05BD4DB\n"
+":40C70000A3A3DCF8C881C6B5222A183E17871EC1EB2E8AE71B4E896FE049A1EE87E101CD800CB7DF0587C3D103D934235586248006F77341883F5365E15012038CE9948927\n"
+":40C74000E0BAA6C982393EB3721E9C862E61E235385C3BEC40DF2E899779F61440883979F2209E013F55A611E8109A071F8C6407BCFF48E240E02780CF3FB2978AD7CC604C\n"
+":40C780002FFB2DC040B0D8222808600EFAC02780303C329AC3A9BA84F8E09FA2208F2017AA2C47B3120C7928A8A075F138F445E8F8700D001CF90B7D5378A16C16F2C34508\n"
+":40C7C0000AF403A1C4BAE921610EC7722027E955C1C05021302C300F0710E06D75D5318350C62D1A061931D4EF826B17FDECDC57FD804DE85501098132F49027823E98712B\n"
+":40C800001B10181A59288062A45004763A4582794853E627A4071A5329F22AD10C10038C6862A6E01374548080DCF534662095833D731A2374A51E9E2C160020CE63405A12\n"
+":40C840004CD2290602E4821002402425E10F4211F50050F085F3820B7B01E9D390037A98027E4A621B40081A3155B14C022C503480D13A25114F995D8816068850E43B5A35\n"
+":40C8800070C0D0DA18F881F1D3003D84BF5CD1101A1157DA068118040340B1C03B15350F017907D3E6687537D0894068051E890A079FC81403AD450109D4FCE23A9ED8C499\n"
+":40C8C00060C0E2CA22407AD6784C9030AEA2C4C1B5EB38A2E0B923500737001A497A94BC4CAE988F1A83103486467F0E88E818621E9232470388B81201D31820070D51C874\n"
+":40C900000D97890BDE386819480C52E2641D324200700D25A3131280C129441C0C3BC6410018290B7A2AE910380AAEA54A51D469E9970123922F21048F4BD354A36180C103\n"
+":40C94000821DEECA2118107D044C75A0D1007E7B261EC255200C811983EF447E49192720943043D458C4621486074CC599896D11274A5EA22D418B1028068E4AA690744D4B\n"
+":40C98000710FB200ECA861C2010765E1882E5CF234E9F42900F55DD930C0A60B869CCE847D0A4E3DEA3E5E82372F429194425E84C41F1053102DC1DD8BA16648D00CC0819F\n"
+":40C9C0007822F46D2882E0C04227B6C04240141C16086CF43D8382208742C117B0670ECE03E867410050BE1C028F40059418F429609300E8C25CF689B902C1378EBD0BAE62\n"
+":40CA0000AE8A5A1E7F5C224103791DD2B846879E3267BD5CC420F088298BE68024581A26803DDEAF220F2E140C7CE86C879AA212E14889047D83FC41A5C240007A7FA110E4\n"
+":40CA400050C4B900758083D4B385E70122104EC67A3550FB475110492EA2F42C0885C9180BA0110FB4020C17EF5A947A3D647C4160419F9FE34BA6B688A1303AD9F48173D8\n"
+":40CA800073011074CE90C480AA1A08207054169C0CF72298C3886A8834B340D5F3FBC970A682E98681E205E8029D627A555220C1E01203E0302C210366016620598800E070\n"
+":40CAC0004C1310D81566400389E05FA90B4BCF9DA3C2B3479F0608E1D3332878BA40418E0D823E842E12039ECA97A00D48182822049C2010E8DCF1BDF6094600A04E74448B\n"
+":40CB0000B8EDE7F105082E25F425C0407874E1D8FA7B04413AAF3EC6721F132FCFA36F960181AB9B604180A841B9E83078C70A1B2EA125102303B177E9F08800510572C91E\n"
+":40CB40007A1710BA14706790200750ECF02A00E19A48848D01C3C49BE3C05747C23DE3DEBA2877AE7890D6BF26046058401C8089515EBA2268CA2F4980B3200F022A6A3022\n"
+":40CB8000B954F13C4D0247AAEE241A894401B3B900DDFEF621002B6ED0037D6AF938BB88D022C0D3CA14BA1894FCFEAA3340887E87FE1F06150F4CDF0D91C08E1D8309B8B0\n"
+":40CBC000BB04A04CA3D855F51251F371811E8A21C8B29F8BA324044C3D8D5E85F3208F311A7A3B0064A602894809692D383E0978F74C8429290EC057590A17993704032682\n"
+":40CC0000C7DE06BC231760050E16001489F1900BF2EC895EE6026DDF2200F001311487E08A622EBA2418C017BC6F5058AACA308620EA6327027BA85F040173942DE85DA1CE\n"
+":40CC4000F1E9995A847A0400AAA50ADA4B880F08A55AE43303D282EB2681102C163D25723D26B6239610012025C5E2486208E6C2BB4E181E91978C69789680BB2C80431FC7\n"
+":40CC80003C568805DCA76402183DE58A2217092A196108087A224C710A8F67F79181EA1DA44E0B14081DE087E20341904D0EB02C3047C7C48363D1030224C0432383C397DA\n"
+":40CCC0006E008865E46471F275C9972729E83801837045E0DD816002E847B2E8F38130469053ABE4C7BF060ED4B05D0581572F3B2E9A151C79420AF5F9F896601947D0E679\n"
+":40CD0000C40F80A0B7AF1E44D9EAFAC9C03E7E3C5912CC40E3ECE8172737170F23C84434418C332552412E2B9C844E23C26A7647480FE295A120784918F738C0FB0CBC70B9\n"
+":40CD40007E80820687A08087C02446E6A1C04C80A473238890BBDC88F10C11808E2222E73005DEA405D9B7C588B024C26A1B3CD0FC404270FF30BC47E4561503D8CC8802AA\n"
+":40CD8000BC26EED3121943DA0E850423C02ABBBC3B78E87CE25C357E16AE2A0451A26454C224A54B1776770F73C989B20052552A8CBC7154409A1EABA3198C4F63230ED1EB\n"
+":40CDC000E0DB0AF92100040CCFF33C170B02113487013D448E5D8A2C3D855C20407E0188643F60CA90030E619A40320B46411ABB06BCDC01746E23209FAFE848D66CF06296\n"
+":40CE0000187D1002371580126326055A287B0D34C8E43D02D25C71006207A6EEC7A6BA880A35A187D5A425D35CA2051950C3D85FE5E80EA1F10A9090840181E81022E2D5BF\n"
+":40CE400062382166B063836E89000512C110C1EB92912680AB8004103C11E260E25870E2F2E829212BFA4C28CE203F0E780856544BD187A409F6193A000FAB54CCACB190CB\n"
+":40CE8000951EA3E23F4066A971B9E08D2F523491E4087A1928BA17D0480A143D83D23DD88C5D3832382AC0589415A1C31DE05BE044204E5C8101700220090F70F01605A70C\n"
+":40CEC0004FC38F61A809585AA004082018C7271E2E8E351E618A2438153C9439F6C6F0B005A054320553763904FDC54037B7454E98128F095518A01040822A20AE341012E5\n"
+":40CF000042554C3C51E0433F417391877A9080A7E94BDBE982207778A8883460BD75C041570BDA12DAB60800A1E3E5DCE19B4073088611E4B9120B6F0EFF1102698665C844\n"
+":40CF4000885986B4C4B0460F77DD1745240905D53345901025C797E1903301E0B3C4ABA350E3D3BCE3D9EFE23D88576080C61D7725B0C7A0415F003D34BC203083D0CE050D\n"
+":40CF8000D82562215E12201974220F611176225BCC403C27026103C140404202DE378F1C4C93E8A2D3BE743C79DE37D2083070304E5D425CF134BD14485C2D24444F0F5F0D\n"
+":40CFC0000889DB12A22C743B7163211033B6098FA46D4C2DF4719240424101A1E4FFA12C2F8A47BDA70AF9C2F2A1D165490F9B8587B86C0C620B78DB7A66B1B9E45A42C0AF\n"
+":40D000003801D00DE2A2D1ECDDE1EE4FE20383608FD15B22C93DDAD3A3EB73E1008F021BB6C08FC4556469FA1D0C4FBA8D81E813C133031077D2F14261176010E75BA04CFF\n"
+":40D040001004C036127529611E279F54991743AB10E04C0102B802317393B11986A027852591BC03F0E9A1B1F01803D199C1998463EC1222C6020388C6088484001A08042E\n"
+":40D0800094A03BD8387C7874235142128920891A3EC908CD2F4021D463054242400D38FB50E84199C001802CBB204D2E97B313F481EF77C102CA1A02136884C3C8E63C8ED9\n"
+":40D0C000D37A1D95EE5358304C10C078C22E8DA690EC3182C4C12DD8DCE2300303C0283383E1109200F7C7D8CEE7EBA001083B589C4613E7A9DC0422E284E62303DD15AED8\n"
+":40D10000205173370770E409AD720881A3C0A63C0AD92062390E77E58049BA474F6F73975485081276CFE6709026970DF244870B54B82E1083D54E17B3876BF0A0079FBC9B\n"
+":40D140008CC04C1EA14B22E0283C8203A09E35487BF220D621FCCF2E20193BE519912D40525B95750F338D100C7806C0910823280B600FA484441D8E3071401D61060019A7\n"
+":40D18000E0119D24F9D00F9AA3BCBC47790BCC00CA536BAD006041CC11D1E83C42DE7B7C80AC16FAD11C7B8848C1A40651D9A7451E08A26A8C5D089A47A01DDC09E6060E45\n"
+":40D1C00020579C000829C7A84037710B8F8F7BC7CF0083D06DA42CE0FC2ECA7C1230770E90F51580F1382234054E14425210980BB88546E0716808402F578C9A06084D03DE\n"
+":40D20000C05DAA81C5B6211771092E049E2460A4808E3B757058F695D9897C3EB0411E57927DC29A7EAC631203B85396E19023DC428900A9849A1E31EDFDA234039E843FCB\n"
+":40D2400043B85954097B86D521E900CD80549E15A226790269848277544D882C02DC6105CF434C91C618F632F0F49F20CD800C8C40080831977DBD284737863D8419E595B8\n"
+":40D28000035E203A8C4789CFDC430616A416A82D50EDC0F88A9221DC08490127AD230A8826068EA306119A148D004E8491BB489E4441EE216441EBDC0CD6C708212772B007\n"
+":40D2C00029DC1D067066241F41AD1F707F314ED0094D4034650850EC0F51F35EE226F53C4C2654E83572EE2324A9E8992AC6CB81051A1E8160DB4CE55D290F5CAB88EC31EA\n"
+":40D300001E2741AA7B98040F69E7888D66E06031EE0E33EE235400F488C405A9F02C809A1CFCE044002CDAF5BDE900E049E04078E14CAA347B88CD3024F7EE98511DB91C16\n"
+":40D34000715142A745DC46EF204D30C31A1E47BC1EE1C130CBD45425C4C54413E1F6E61077110A1E0CD53EE2223000454082034950051D069C550081B48042CBC29FC5E0D5\n"
+":40D38000D9C2CAEC136FB9D491163B886840347D8B3A2C98073740631F33971302898F7275080A2196600555160E803C4E9EE21B580E2BA81101E3902A605092038A24EECE\n"
+":40D3C000B80B8CC6B56430207C969C43C819308F724009C5E0184103844028EBA6A176E91B5D1E3E518000A24C809C8A187A8F08CB10100AB398FA2828FB88612C2B0015A9\n"
+":40D4000031D9F262E074A00285A503103CCE0B7BE8F8BB7B906C3A16CC000D220092EBCFC1E14245EC9D51EE1A54CBE3D008F1B4B885BE4EEA2F1D02082BD4ADC5E39DA37B\n"
+":40D440003E7BE53C408852376F0A12F48CEFA5E12A7887C117040F93BB4AFA0808011B749F9AF1C8BE3C8048B47A684440A16ECDE1D1DBA3E60501280E23D0283407CBFF9F\n"
+":40D480000FB38604DAEE40621E7BB4CCBB20646D1E021DA442C301DB6BA3D54CA368F1A54074A2780256EA43B87F586FB87FCC02580740814DA04C680C4C3ADD206611033F\n"
+":40D4C0000D01812EA4F51260602C8600409301EC3A3DC3F420E01355427872B4B13C008EE1F960093CED6E88048F70FDA6051A0280E454FA3434991C46A1D488AAC2018D6C\n"
+":40D50000543C9BA443705BE941432E0E3D3764F74CF0F4CFB9F74CC95C7600A0FE09829DD33046702A7017080EA04028BE89491E89922034BA8A2C48E21FF833E4B87A7922\n"
+":40D5400064278FB079C896B02964A020067A896859C7F41C4540B9D7A9001E4FA12B9800A9E28443C257242F243BA570B0D707906A046295206805C8F54B588452B235C2BC\n"
+":40D58000CEB118480332A6B11093EAFCE10964E21B2904ABF4E678B52654A9030165036AFCD1124D60746D3C87E2D4702ABBA57CCCA929B1675134B8A18D774B52259459B1\n"
+":40D5C0001AC0A70A0F10801A0319EAB27234411C68818E30738A884C676985A11F386885067BA6F0BC92089744C81048C774DF2D87090EE7C02090346444220792D4A1F5D5\n"
+":40D600006109E42F88563C96A72F9F6BC40D1CC9034BBA5087CFB7A3C477C44D02C6AA2A43C1586B0484F774B8102060802058B512813C00983C908C580440B12A210951D7\n"
+":40D64000F477308E409314FCEB18252060F501D0C317616F8C9C00502C1E862ADC160D20487BF5DD00841D922E259183DE712200F29DC1038791D61C4202C8C23480C1FCB9\n"
+":40D68000F38403440B1F4B3C0AA03F8EA3E8EA3C0EA589C05894258804591C202162168C1DD2DC5E494C4328B8BACD7269401D08889C7FC04D03D3AD0608092B826200D0AF\n"
+":40D6C0003CB89A5978870930E82DCE524C22EAFC6484A500D41541A074757E2A679AA5F0A07201C6502C701B219672710187D4F61D5F88A8949846CC4A6C44B804591A5EC7\n"
+":40D7000017E440D6F5EB09746338F57E0BC049A55E04FA04975186EB8D04582F40E0CA868883D5F8080126755493460280F07FA3A352041C35CB3F65C017575C089BD7FE7B\n"
+":40D7400025D5F7E8012374CC44EB813E0AF60E608BD10468F71820F68C217A30910340A9260A082138313E817FD5F7463EAAF57D026E204DA00FAC58CFABEE889A48005F22\n"
+":40D780000818163ABF550EF16E209FABEE93022D022CD2E0ED8EC1EAFBA2238792D2502E4011DA16A97097E124AB594F2DB717AC8F8486E970F1F2FDA884601781FF4C08F6\n"
+":40D7C000EB36C54C3EA90F130C611E5AEB37B3EE3593EB38A523D1038F147B2068CA3603AF56980F533C88167755001B43CFA24F080F0C7C5574308020F1F5F114B29A479D\n"
+":40D80000A9DD0802E65128011EA800302436057A6354872EC1CB1180D91F8F00E47604B8427884DE096E2CA802E9B4510CFD8EE056540E824D2F461518540407D2C2020F08\n"
+":40D84000E44F0064D1148990ABAFA648B9023A45B8CEE057D966623B758B8913488117001E01B0F00128F8D8907B2CFC423E2CE25EAD3C10241013BAC12C6C960221B247A0\n"
+":40D88000E5238981E5B7840013442DCF6A440919AE84110FA9A494E94F51ED5A51B9C00020ED8080B009FC78425E735410B90004D00F488080B938FB1DC27B2FDC4B00B461\n"
+":40D8C000D10EC7022C0B1082DF36178F73D517A51A4C55204601A812204242EC3E2E43E18C3B1C08302C0D00432F05B208065077A4911C640825E1209100BA4E844AA3635A\n"
+":40D90000B5D190103D680022420157114512A3C2F965DAA9821575D570922C59F604EEBD621043B5EF8A207A9ECC7B13E44C943D0C6C2C09413747E3932400FFD74FA44020\n"
+":40D9400017C1F7AB6A88201589503C0EE9AC51E79BE2170F01EF85F7C4030B84005C83050220C44F340181FC042FC0E1ECE598E2183B78F4B972F105C5A5BB84EC441A3DB7\n"
+":40D980002E741F43281110CE95305809ADF02131D582E04E04727E0814EA68E54082124C398BC2061A88837DEB388E8280583FCFE1E0E4B3A80F602E0411E9ACE1ECC9C166\n"
+":40D9C000E6A065E46CB1ED2C312EC13EA7F33A3A1E81751A50238E4160D202E208443FFB3F80BAA880884ED9C8428F85D000031E56B20A3E03C87A4A8DDDF2CE261859E8C3\n"
+":40DA0000C4F1A405DB7F6548487E501EC4C9DC87E4C4050068F3CA38B03AA1E56552398C7DB7164C1B6C880668D8DC41230316B01A9E0034227B414E36100B2A013C13F49C\n"
+":40DA40003FF881BD3CE060093A03970021DFE84C411E4EC9907A3AF840904420043B8D1D087104822E97EF44F4E9AFA18C30FB888B0DDE30030C38D58054C6EA5D334A88CA\n"
+":40DA8000F40A9403D0384E84F9F0645A80F3487663C220393C1477F2A1301380E3085B74A0155D0B8C584163D240A2C30617328C2304A50281FE893012C3A6FB06F5A014A8\n"
+":40DAC00089B0400833FA5A504A5F4E78198FD084E255DCE106A9565C1065180005143DCA5859E3A2547662988826B151D9A44F29F668F9766919F6690B44DA998E8A8D03AA\n"
+":40DB00001803180FAF2A850F3786120CC0184DBE90383850207AC83C5A1EC7C0982F24041EC3EA4BB08D48B8108B502BACEF460C02CF27D0979BC18BA807461C00BF1D25EE\n"
+":40DB40008C180DBE35D81E231E3D6F025D5B7E2059B01F9700416A0616A06F55849153A3449A78252A3C440878E2C0F4E2F89BFCFDB4895EB7B7502AEB7B431D9207BBDDAE\n"
+":40DB800050FA71707ADED44F840734F1E201CACB202FC26D423872E353187C91747DCA8E2680DB8220FA25D486C9221D985422FDC3C38CE00310183D0B7B06B88B60B7A7F3\n"
+":40DBC0002B90F1E0A9FB1DC90B72A1DAC8B3D62B6218746298F683F2440702AA9B7008B6445BA8703D8B1E06472223040978104C79C981F850547AC8B870F040A9E464D1BD\n"
+":40DC0000008D114C79EBFA91EE27913CC8204BBA9B47B72C883F0050EEA2E13E49204C6B04CB81A0D21331DD01A21CE83E840E27902642435C4AC72C3D50A021282C081979\n"
+":40DC4000E3D1E859765610E41F8F1C9432C805F021589CC690880915E0388009161D1C742111420E0C60E97A02754791793EACAC941D4AFC45D80809163D9A6824616060BF\n"
+":40DC80000D03A771CB0980095790087E8A261F1DDE8F65598D66801B200F17400C58166912881006B053C5D324091692900602399C1815102811253B29078BA187D2100438\n"
+":40DCC00066F52CF8983EA1FC1ED4EC1EB9AD103B8DB00992075E0A181F400CEB9B92EE0B9127AE9E1327ABC4CBA248CAF988057D991042D02E0C0E0088205875AD60F6BB45\n"
+":40DD0000D0F55F00865D36D464E239C644061A1E70AC44404414F2CF3239C9C66023DE16062262DA12C11020AC930F0ED61098F0EA89E501CC8AA1600C44090139B9821D15\n"
+":40DD4000A4BC79894204971D4ADC38A50066B6A15FF613D888182144A0F230791AA5E9AC5F79B66CBB38A44CBF282F098E5A98A050040A941D5C98400821DF3265E59691A9\n"
+":40DD8000AFC008183A7C951256510F4960080868965E25EA21D3ADF3C8402D406254068754082540856E3DE46019B216841CC4518028E29F4B9C31967204E77E1F4BB8179B\n"
+":40DDC000894ACD80288205480EB6262E28D8D5E022007220A418253C954A80EA245F930C0BC070C7E507F2004661E4A21FC2E19CD8EFF7D2EB4DC139BAD300B909890F42AD\n"
+":40DE0000771106103C0318C790BBAAF4CBBCF104121E8A21E84E89128F854A08843F19C780143D77D7388FE21759B21E0DD03BBA2520BA20E47D0C6E2591AA591EE59030BC\n"
+":40DE4000787168E2B9184B20DEFDE0C2C70591703873D2C3F15D34BA0145550C40D71C09F04BCC44081D0037867D0BAE51511AD54F22FFC4D763D54EC390BE233F5CA22272\n"
+":40DE800033264F065D09A259F1240411557844F069D87C05D547A3977824F027D7294D16A0BE37120245AA9321E50870F135C0F5CA499A42A934900021E13E03485326B95D\n"
+":40DEC0001099428F519D88EA7B212803584C2D437EB9454C0E343ADF944B5157B90AA49CB26475C59A1E515B10E0F0193AF7B089E078D31141BEC9C2927C6827FB215C7955\n"
+":40DF00003D188C65A827CC0AEBB3E347D0A9025A8B04F80FA06C32749D0D49D14C9D05EE5F0EDECA10E078088B5048F011306A8656A08A64F09DDFE1E5D721C44F09A909CC\n"
+":40DF4000869062BC64B20E4F44789924F0ABD71BA84D4241F454D098C4F8E18D40D8EAA501EFA6218B2E9EA910407A1B8B51E33FC840627CF12787F1FC0CEB90447BD3DCFA\n"
+":40DF800067E31FB476244F01E3D05DDFDFC439A144028285F801DAAB0219D291170D00589801CD104BD70B431602C75CE89001DD8463C3E307D30FC88023085BDFF989F518\n"
+":40DFC00051821D6B80875C4D1791B80CD46744005D0AB45D7140B66EA1DF9C204169D4B6C5741227BE2E2105021137898C19EBE00951EB7471304AB1F8B3C77C00A5BAC63F\n"
+":40E000009F001E7F02BDFF553D8E1C75720771300202E777A00344EE4BA03A47410455E006B9D7D801258B4CBC0966774BC81FEA2701A9E2F66D198885F5AE0EF460354E11\n"
+":40E040002EFB5C43BED69538A4E64D2B972C24A778C018A090AA538016E6332FBCC2049E40D324009F38CD08080A15850E11B019A86171F951F33A20F58C6091E4BF480285\n"
+":40E08000081C2302B9B4025B809E070113BC9204B9A2188218200BC379620A849DF6E23D54642220E26567EA0F700D0F19132EAA68110E304404E2CBB676C813EFB744637B\n"
+":40E0C000881266081A344B818FBEDD53AF61F1BBF1690F061C8D62CFAEA9C481E278620F045E3CCD1B160690707BEDC44B615099EFB7012D855267C0CE025B0AC4C8870692\n"
+":40E1000022B93360B0280B6AE501160C459264461C8802D85A4027A5C2010E30A01DF7DB588839A1024223749C75AAA90C20F84E2779C6750EFE342EF56220B04120CBE13F\n"
+":40E14000FCFCBEF43BED984985425DA82A9251410A8429F445CE3AE43EB9781EFB644BBED8D2EFB6243BCD24BBED84A107BED8101E3BED7D11E39C4E0909E99AF4CCD0B36F\n"
+":40E180003EE921C82C42E060B24C0EA0D0EA1D7624089F43A8B43AF820087A2790BB0D34415EFB54202CA90810C4A81DF5F020076E70880792145D0F003E4A683EA07D431A\n"
+":40E1C000A06947A7FC47904C0F6692880E4C029D8016618103D97943AB261EC7913E1C504C0600877C4F97500B97B3A247C84C23E39AF39A866426CE1023A8291163B2D19D\n"
+":40E20000048299449630482EC033120E683995503BC3CA82C7A4734744845ECDFB1ECD9E1B8607B90944F12C4D610C0AF0F610F5AA2095C167971CC4B6014703A80E29A1C7\n"
+":40E240004C060780805084F0EEB8E62C896DDDFC43E5C541F651E881C454708145B00FA4002852EFA01301D0020052942C383C43184068BC1677DF5297540300472BC69EB5\n"
+":40E28000A956202492840C9CF2BE340081EA247A7030581F90EE1DA1E2B28876E9521CEB5C41705EA744702CBBED0040CEEEC92363CFC483448017EFB9A1038E324083EDB7\n"
+":40E2C000CE81004D4097A8384C00ED8F023481FEA4D92EFBF93234BD44BA18CBB40C241081D1BAE246F839104442EC3E383BE27C7AFADC8F5380D5063B1B4C46B0089F3CB9\n"
+":40E3000002EB838B48084057A00010EA2243C38C1DF6CC801398B88F7C6119B08F7FF41809DF6D0E0466E2861DE1B8684B8EA260401A2D395D895B1000C147A82AC7BF0CF1\n"
+":40E340000804ABB2ECA64134495EFC2F2033AB91C58257BF0B480738FBB88CCF4010956C2048412C52102841CE9B1632A54BBF0B9361BEE35741A03523EF434C46C9F9DFE9\n"
+":40E3800085AD00C6E1FE75DC120020521671BDE302CFA0B3BB99C7B1E64400ED7DB1F5B5D8F153D110EA9C6E9C037FBEBC44CD0901400C8C2D0A00861442150EEECF160224\n"
+":40E3C000250AB5020CA0094170400F03CDB24C821F40228CA0010199A112493EE90A4C191C8F81CCB840B23DBAD64074DB5225E383004C8809C541CC5AE650220AF9A7343E\n"
+":40E400004681D4681CC3A1CFC784C27802BE3CF12E2E30205FB5C4C44BEA3021CD4D108FC6AA220281FE6303120C722080AE8E311E91EC9148E6E90561C22200709A0810CC\n"
+":40E44000613D0502268889143A84214E0E102F82062E5F01C427BC4E012ECD371E9CED13080C2CCA0C60A057907231000CF440032C7D38A384FE0818040C2F2B8819D9C588\n"
+":40E48000D1CBBB9C8B9C2B080DD2B80595F85C8AFCC0B1C0C802CD2B2B10FC077B4B104CA8521F40E04EEA11EA0A82EC78A236982602DF03BB8FB3080415D0D88F12B610AE\n"
+":40E4C000128B8883DCFBE59BFE209F388092801D0F0232101D0F823110A0383C65A444C1746FF8CA304F60389E08C9806CBD01390EA91D203F599390106F5D685DAB0020EC\n"
+":40E50000B826210EEC744A91744A815FA21ECCF3100B8872976B6E90418FA48B69210EA044E622013C10F7D791952040DD3F14395C9200EF80EEC7ABFA489E08817207B184\n"
+":40E5400050863C84E50E9649360144745A04C0465F8891C619280460E82011E876841D05A3D0EB0821C69413B077ACC9DF8F01677EDD286F573177E2711B1DBD2C7C3FE476\n"
+":40E58000BBF1211238650F47E4C8E1C110818CA007709FA6156704E4085C72486E6080280AB010CEC1DBF9A274814434295BF0EEB40BF9C0F58702D8A3E85C729B07BF1292\n"
+":40E5C000162453ECB98235C4F2645927C0BB1687641B08757F496905CB91390885C60F840127C09264372F461DCED47CA4523DF7865E5E97160031050D5630F7E2310F61B2\n"
+":40E6000060CC3F77E2225A63C2C8D01EFCDA237C90208EE0370B105031324B7EFC481024F68536021528A08602DC0CEC78C2263B0CFC7082816E67FB0A807488C3DF1C428E\n"
+":40E640006379175D0BB892020D64791521121D97D238ACC41E3542527416F53524941E9433322C0DBC3C0A0EFB8B2F24498FB27EC703D8F59240E56094D900A841A3252E05\n"
+":40E68000FB7722758ADF33272F987D973830E58D9441627437BB68A30C96500DE2C7B27DE6E911EB9C040460B0C03540D3580927812057BF02878D7408C64B880DF5EF393F\n"
+":40E6C00060DA0CD65118E8405C32187A8702623B66B0DC98772B001C3D4FC5D74A287A9334420683A2781327BBF0510BB2402A892872EB6311EA5EB1278142783135CDD8DA\n"
+":40E70000D303940315F5DFE13019200AC6101A7B28065DF8585808C0980029E91A069420F7E08082A2AFA86D50028CAA84005FBEB0C6A2400C01948CBEFC12481729017594\n"
+":40E74000005589A48F3CDB0F3F282ABD102C0420BCA9CE5A2162C23904A75272C9E41279ED484BAA405788077E0A99149180903472A4863116DDF8288459744ED90BCE0077\n"
+":40E78000116C0BE955099640D12A24C224018F02A38CE2268955DA37E3DF8367D2953222858D715643B03878B33847712083F43B48985ED9DE12602EB91C0E9063C56BC440\n"
+":40E7C0007B0A86893797E4241132106570093261001081D2AF624116410183E049E909FBF0755340961C72FCCFAE31CB22DC4E9EFC033028D024871CBFE46253239708B70B\n"
+":40E80000843BCC04C7ED72318C6880501FF91589F61AA980C44D2A4C2E44D51EBC513C23F1EC814C00F9DE004C002EB284B5EE63810187D0B21078AD9201672E0557B106B5\n"
+":40E84000CB944908BC3B0246A8BC6B8BC6094E740066B0D97800012014AC012EFCF722A40A0E821C6B40749A232F7DFB286B0C9E6015234055F2B2F0F7DFC10220B8C47BA7\n"
+":40E880002D747AA979E28C4203410F1F55888B8930FDA0BA274817C8B60BBEFE5702C0826A7441B024D2F511C4B8747BA9853D1EDC6109A2259322EF82E111EAD9A1CC9473\n"
+":40E8C0001EE6DA2EFC0063BC6A640814A8C24049149823D0B6A893BC92C080427C00EFBFF33A3AC9FC7A92C08E41C0162E00AE39B85DE70444E8418708494EFBCA2ED42F4F\n"
+":40E90000301BBEF3089FF27F38DA2C815EFBFE40495105BBF0645CC1554028DEB1B1301029711CC160204B1C983006261023763F1608AF3D9E98E2E35860D9E04360302DB5\n"
+":40E9400042617808DA7DB51F380A90108294F00B0E82288EC841D62408106023AACE1820C4842C6AC38B703A1023C9A4C8F522010841623A43E2108B047A9130BBEC890058\n"
+":40E98000540E087CA3AA34780BB013A48244E3E9BC11A3A3E1BE32C54037268053C956C4090488B09F49023EAF761CD2810489F09FBF0B921490F658E8DDC514ACAA20B445\n"
+":40E9C000AA680127D44176A76130051A2378140F5C5C802BDF86088126D54121C9F2CBD52DE2410F5D8D5A2101072F121BCD53040208732101405F66B70C4900B6F8185220\n"
+":40EA00000189DD1F00D43013FD9B2225B8000B77E1B0FAD534C46004C3EC6191288781C3B14B06F4A0EFC38308D4A1058E93B127107948034058C38AFF184C16777D5AB951\n"
+":40EA40007784071E4108C1DF388801E390423077CE19965E457B3F58AE0E4BF0846019A20789C108C00A9180BF7CD3908D0A24682E813DDF34E9DF1804A80372A11A21993E\n"
+":40EA800033E7EE0126409A280680644C041ED4569EF99F1C28E10A04FA45BF1BA5440303C2CE5C8C881D991E2690546C733ED20A728A0443E975A104B9E590F617A1F54202\n"
+":40EAC000288223C0E9945E46984659F7D1D9966A859854598186C00655719FC4FB372C415EFCFA100CEB05339B0BC112E2271A1995239ECC22796023E73611040A7432A126\n"
+":40EB0000F1A9510749FF3FBE0825D2B24609130241A3040049622B1620BF2B432F50A71619F1C26917088101EC97C4BB0038FBE709209FBE7493EFC3830901047C62905D9F\n"
+":40EB40004AD45794076A2E9746058805C7AA04433C008832EAAD21EC85B3ECA2048092EA9D80E6041AE74F4900204780006F941484DED5F388D204F654208063CF53751F3D\n"
+":40EB800059CF8E0CA03E0811009A0809A110FF3B23822CC8148422CBA47888EAC27039AC4428821E23B019840680A40D3DC9010C6DEF9951F64409754121616B0930903058\n"
+":40EBC000A4160080007D0C242CD69133ECFCF21049A100FF359E47522109960850B39E831E0D50A22038033852531E501679DCB082DDDC7620B82C456951C45BEAF2A234DA\n"
+":40EC00004B9224200584E087C42BA239EE25D20488A03921E1CA2102010D55B0E06A83D899EEE2A133B05B8780DF44CD274E1278C2274A21E4E21F8A21F4311FEE8983F4B4\n"
+":40EC40000D37C9530FCC006570B80CC6F1C6030FC6A01667902710F4611E03502623860617562A8B1E2CF791421049002B2CB66FBF09A9203CB5C09A0D777420B8CE103F18\n"
+":40EC80001C44EB19B482448F2715A30449EB17A1C2F803F82DC9F08471168712EB14801E00F5E7E00A09DDECCC3C7EA04111509E930185E7A16104C7F30BC460C264842184\n"
+":40ECC0007867D534A21A81C3B06211184121981098401999DD4DC2364A0784A9D0A004192509240B09810E12B022CA3EF7C410908DD132151801CE908068058F745406206E\n"
+":40ED0000E90050790CF41782489E259E97E843FE98021C0CC01D1E256F7A8A90F06149029483429B4110F239EAC30BA4AFC7BC9C4BD9CBC36298C3401D8538708021035D0A\n"
+":40ED40004B3F5D8116391393C6BA058F56892203966162A01E350588E4FFAA06605A00D7914F845838410D3638931E1F3B10681298408D3881006C4FEEE711144B02600D4F\n"
+":40ED80000241740D0F36530C2002A08A02B2006397D17883DC06C22A836349600C75DD0220F80C29E8BD44F943D8C9E200101DE36C231A041664B4F5DC791EC68091E45312\n"
+":40EDC00081060D012BC8A863DDCF226B893DDDBC4040041677737242A22098A7DD81422B0700BF5522C92214F7B76981E71058304810D16517915E47BB99840F33A2840571\n"
+":40EE00001DBA5038400248231643F10399C08E2070280DA12FD35EA53B800E0404E2A8286081167E1368641D46BEBCCF10201B15BBB9A045747DAF2C407019DDF9E24081DD\n"
+":40EE400004D4794A003CE9C9720634E7C22CF774918B2980A05A40B00F1B784844328A4808EFA3010380260664C21F04E89029E457910601F0F0A0EC631107C22830D0FA6A\n"
+":40EE800011A80B8C24D115D3D46255033819C2E140024F521854D56808B68031ECA7E1050783301314BD03303D45E243300382D4CD0F2E5C1616B03CFB890845C2C018EE57\n"
+":40EEC000FE443BA46898DC7C8772481618F555711A984784D010B190867DD177F1C11681302BDD1803B1344F1C7D10301316E691D6AF0953D348E53A0E07E0C1A000D8BB39\n"
+":40EF0000DD00C20B10F54C02F23A7131F1D400860098264C94DE0B1E1A99004C5EEE81C117D106C992801804CB28A121948605164AABE1F5A8D91100BD5A974D648C680CFE\n"
+":40EF40002580B0098BA5B751CB18300B7777A0FAD4A440A33FBB5A04624677008019044162DC40020BF88118D106CA0E9C161292082C3024183A351264C776F509FC63085D\n"
+":40EF800003A970098A85B5FC823AF736D1E92B04C4096C0E38E4802E1047A1B34962201C6A4681D7AACC28C1108131A4B6F07721E2EC02D8070546AF4BB308C25B30088662\n"
+":40EFC00005BF5C579659F883A359200C032181600E0263196C000E8357821FC416860EFB0810241317CB6000AC0834A3C5726802631772F4084FA3EB3265000FBB3C44991D\n"
+":40F000004413183BB9FCF4A182C1644328964400B19C2C2217773395F350008E7A64B1A54A18290CAFD34A4291A54792A4EE7676D17A6D146938D2B2A52550654ADE5A19BD\n"
+":40F040005B82A64D6E938776AD0B0322239B3009957183F7843E859D29C8B065D231199D8BB48676B86E2295221F2547C696174B9316B6286910EAC246B551A527D159C298\n"
+":40F08000C104BEFDB0CEE089695A84332F5294B37A058EEDC5370AD41028C700473D43A959CC693A05BA4343F5568A23985FA7EE1AC9430DAC3138869E906940F4D0B8B002\n"
+":40F0C000401814E4AC6C763A2153BB89CE92A001A9082300F0A101A0D0C0786424B018163D8196B52A4674650A480C3400D232C6FA14916F20138EA59058AB30067B3B0C1E\n"
+":40F100008268711D8BA1CCC91D8DA3C015E8D1313047108BD3F24211F4E550987D261824B718FD9064724214495481A1CC1B1DC3BCDB611AC06E9DA71E4D38231C60EA8280\n"
+":40F14000458AEE108CC1448710BB59904523481C188EAA3804389E098B5DCE98204F48A188B96EE1A8F0300910B7D211460FFA0E806EAB0CA2A1C28F1872844191901E46A4\n"
+":40F180009202130151E2634519F7DDCEE27B900410E2541E25F78828098260FF32AE5A2EEE40306D001977788F91CD0C242B334047A82F088DD21A10262BDD223C16544724\n"
+":40F1C00091501118081106F0102D020028F1218529FC6FAD8C35100CFA0AF8BA65C8B0122380063B249C40A3EEF0F00881500C83EFDBD2087BA254CFD2A06306CABD0058DA\n"
+":40F200009E279CF456B81207BB998400B910BDB2B866F5E044380375A2388F8406D4509021766A604A2008058DB818180DA43A74E469D097045D3902E4EFF38C5180D40CB5\n"
+":40F240008100D00104A6B2358C60408901C41340C6200A02F4481E8AE3A42C278601EAC130288F427620D1CD3311E03B1C810E94F9200C293D807CEFB2038DAF50E408035B\n"
+":40F28000E0BA12BF100D12EB40CA43F8E798E46078C67DF86D884B6892F15ED0C52A051B74EC0B6283C89E06358262C16C007947B0416EE875208033E3E3E35AC010420937\n"
+":40F2C0002E9042098AC5B776B7963DC035010A9801006E0CBDB58657B80827DDE5E562210347118C0B0EC2408C11B0E001E129E011923A9922ED6D51EDEE81C873163B60E7\n"
+":40F3000078804134268C1EB554113C2F712F9484F94004BD269E211F7EE91103EB8C81D674A19C76212FB2756421F3685908413EB13D0EF33419181498E2C40820AFA52F5D\n"
+":40F34000048488023F0445EDC660098F20B02627D0F01983EEC034128013E49EF3E293F1850382D78406062530A5600204C4EEEEB2745059028DF207B11946A7024C3DDD86\n"
+":40F3800062D0A0BA049B7A68E40070642CE8D5E48F20B38E8F176A98975F9E0F25D4104BBD5004AB3445CF5873A0C14BD2C105A0092D83B48D0163CB6CA3DEA68881E5B01F\n"
+":40F3C00059DF528236865EDBF82EB295260D204B4E1226B0A074068688A040E4EE897018750CF882640B1062086921C403397CDF243D6FEA21060551E478E2068820F0C73D\n"
+":40F40000C6F9C4F5F23DC8F7D6989700701E294CE182AC070F476109E0C1B2C4680C67D0F02A5300B61899640827361010769020262AB018CB83850087C1404478F85E94CA\n"
+":40F4400066B022CD50E31C09763188F7A96172E24160A938392911007DEA5A89D34A8791A98DBCC3C2DB425C79B1CCFAAE784E0E88DB32180044E001086CC5F2F03BC0816C\n"
+":40F480009DC00046F79B5CC460F6D4B104BDEA7A407A332904BDEA7C84DC30E4707858047BD4FC7C12E83EAFB32F6CF7183412F359F1B1681A60C8F4301361079197489179\n"
+":40F4C000048D605E5622010DDEA726437862707BD4F90014E1A620CE4A609F08E3522E9F95963C0EA23DFB909E8FE0B026177A170F97FD8C241A1111F0240ECE2C3B110179\n"
+":40F500007B6128D8299909070C85C10B82CF38651FB5360C3AD6A18F51E78E8D60453008532E02AEAF5920BFAAD246104550304A050A0EC3332E3F3F21F4289149024060DB\n"
+":40F540006CA2ABB15947B66287350444647C81AA3D8FC83D5EB045B757AB976F6311005AF9D0EC7D3E2A27C62F24CF62610275518039915916826201DE2A62127797C30882\n"
+":40F58000222398399143E770D1F547F8E83B8BABD78D871E9F391EAF5F40E8ED0FE2034FA050E06840010B90B3C5C0C6060C416757AF2C561A3D21FE21D81A07705C8967A7\n"
+":40F5C000CC90A5D5EAC89B8689BAA854E8FD887712BA83E882102834EA0F22E7FC039742387C83ABCBCFBB24858F575D90DA0A1A868F579315A5E0A9F500008299A4C46E67\n"
+":40F600009208756AA89999A4AB5260200222E42A2E4C919C3FEDF782387B2DEC8401E4BBD41F89A840A03C9B5D7B7A20F901E3DC32207A5F94C72ECD3A1057A3B2C498828D\n"
+":40F64000105D10CFD3EB84037B4B6C4EA1CD0CD185BAA8D87AB9FC7B519449208420EAA121103AA840441EAF232EE4611EAA112103AA5A0442A1E254A3D68006C50E2E9D93\n"
+":40F68000711A9902B28628308344108210F6D0749741517464F5BB7171B562F0ABF17AE8C04593CC9A9F0BD366653EB534478FF58A7833D90003C910A40A75B599450E3043\n"
+":40F6C000743AC38CBC9FD839B048F5779ADCD05C8F11BA8589088D94C060268AA080F119B4198474774EF0E600884151E43BF8D148430043C2B5A2615B4C42B405AD0D8882\n"
+":40F7000089FA9CB2F252609D85D187E15C520ABB96551CB542340752C3AF70902F6E32480A2391ED62711C01111081EE38E232401278111548743C51369E7248F88EC47C6E\n"
+":40F74000C39EAFA82A4C04EA8052EED56300F3844C5BEB02341823420431D921D5D1A5D69A239C3037D30123D5D287D5BFC67F25DEBDC80A08F56FEA0731066809DE2416FC\n"
+":40F78000110793ED9670C1430805D5C06753C7D5C006250F48757039174071720F75701A1D5C028024A33524C7AA990FAB80071EB898E0101A1679B9011024C2B3311825C9\n"
+":40F7C00041A21D8EA45816575984F479226B073D5BAA61C9201692C0175700A202F2D0043A67567B2778834864C5EF54EB21ADB62EADFE4C1F55F1A878B5D870C3E2AD7345\n"
+":40F80000006AB07AC7B10ED40B109C13BB50CF4212E5F1103C74E853389A05D1DE790F986303C74082111108103E94571D51B8843CA49CBAE85042E3442034820E5DBA5D40\n"
+":40F840002668428FA2A5245126313D0EC800205959D6028A758182DA3B62CDEE2CBA6419D6E290A24E4A04CC4764601D1E51E449131B22C16C88C5B3EA084F72F084E2E343\n"
+":40F880003D5BF45A3E44851283CC93089DA880C62035D6C1C25805E6882C919A6882A549410418A523C6470458940688290A23627C950C45E60A0449108BB5D605826830E0\n"
+":40F8C0002C02C26831EB3A222E48E64B00B40BE75544057AA3951025103C9A0539067880054F00152EB4A22BA98BAD2910BA887175084E874C6599BA689BDD7DB65E0F5732\n"
+":40F90000431BA975C2EA9C9540CDE0ACC053EBE0674D05C330D03374B883817C025340CC358CCEBE053331500E05340564C0187B04A70776221760DE90283023D7C0C631FA\n"
+":40F94000A4123F66069252636B0CA813C03F5EBB2203F48351D8248B3EBE051F46909B3C2A8C5E00D22BD471E2C1AA5693BDA5BC24EF5F023A3BA974B450B0079DC159C072\n"
+":40F98000B25F8888399FBC09A7322743240532E4042E804E655C738A0480C41D8E03828015A5A12608E0AD01C4486DB0430E1250278282EBAF4747C1A342057A7DE075DC38\n"
+":40F9C000C382B40B8142E4601E82E2DBA7BAC7AFB450ED7A810E3CD4CC2047706E21EDF0A2608C2D84802BAF7E9A602B70F12DE156E8741620D91805FB0608E1D785222B93\n"
+":40FA00008004F1BB80247C7756236F5E4DB1A110130BAF274733145CC093874B20232F5E4F88CA5C20050A57C803431A9D0F8AC43E7B5E2C036037A3BD073070CCEB09A04E\n"
+":40FA4000680B7D78DCC8C287AAAB47A344C404EBC6F4C444055510B42844B487D47544E8F94BE440934450D1F898A0A47AA7C24283CF9D841D02001210703E01DF006D8F68\n"
+":40FA800083AD8408EE4FD1100188910600A004C4C16421E823D8ACE3A147104C6DD1FF908881B1A3FE100C9B40143D001104D710747FE87616D889ED936329A01F0C23CEEC\n"
+":40FAC000B9C899F0F5989CE685AD802D2601B2647CD12F88464C8BC4C87A3C0C5D784290285380FB2A511026806658075AC5431642BEACD454D0F0223C9A3EAF44134C2F0C\n"
+":40FB000034830BC24099E56E924C80259FA4FF04B2C1A824EA1E111A18200049247CBC0C212901D2F227E12F947AF0787A0B68C050642B303AFA790F31AA18F970E09D9D47\n"
+":40FB40007D2CA6C44C97959E0B66761EC30A42E1844380D3AF2317EBC864EE422D1F517B56FC9C044F05CC23A3EE57AF1D0B4C6C7D70D45C675E7AD4BA7AFB60C270C3C6DF\n"
+":40FB8000B5455BC87867584962400EE4BD881AC4AF755AA04F0A9D9B08208F362F1C02865D011A2BE2A5517FE8F7D1109BA00781C05008FAE92932F490F23058B3E190D1BC\n"
+":40FBC000215BC0F22EBD94545E59512EAEC12024C6B10976AB19C39174993C17FA5950D8CCDB2EEC061103A63FC417F31E2A33827D4D3C40B9D4138004B0608846255A9848\n"
+":40FC0000B42F8438104060755A21DCA6C52553990297B5FECB507A62D4E0583D441127811F2DF31CE28CDEF12C094E0200B9CDA0059C4BECC083F964F75F728D47A1D7DFF6\n"
+":40FC4000A3B2F111B0138868F4B8E10434FD394912C271722276F24954F07A0014420F566E100E72174C799AB8872F428B232211B4BA40B7180B7086B602BC401F01AF31FC\n"
+":40FC8000007C08B09816E0296E23601F3246C88A014255D96B1AE1492E1504E200344A0F417F1EF3130CD0C09036370D2F5888068853E7364363AF525027C0BECE881B877E\n"
+":40FCC000C08205060EBD482CD6221D7C02ED3D1E8821175E8A10F06DE41109D040A0127831307D477620F75E9722018F685C5A1A3BF21CB22486D98009790B807C11F02C0B\n"
+":40FD0000601D027C2CCD0A2F54730E6778ECEBE4120976B71137B27E4B13E003412049E556940F50AFAF6D11B36175DD8161F41E011D8189B7B8A1D77705B3EB0D9A86D0F2\n"
+":40FD4000827E6CF703A6201EDB4811B8EB014090F8271038FAA17430222215C60880FA63F2EA7C9583D00D19C10EA7C86F9D8B22C160ADB45D0B07428DCF600112FB10C9B4\n"
+":40FD80009CBD4F8E40D8785A980861E70303A9F1440C40006C0823622C3F1C7395700753AB8881272C1904C0905A081DE60820C1A06B78EEC07A9F05E58D61993585F40D81\n"
+":40FDC000321012340CAEA6E91EA7C35FA990CBA9F147A95D4583115FA9F0CAB9808638CE720005F5E378F87114422EA6382EA7B244BB4A1CBA9EC0491E6BAA358A1D4A6860\n"
+":40FE00003838C2EDA02DBA9EC52038928A443B712D122D162D1E008B40458DF9D0C024896840323948447535316B44C45A1BC3463D8B603D4F5C862A211421D101361553C4\n"
+":40FE4000EA7A6188440840C047B7CC45805826EA7A4202D3D85C07D08A43E1E1D2C6141EA4592CE0420BBA9E8075CD63849C0FBC83910541D1B0A01107530BA9E9CFD420F9\n"
+":40FE8000E2CF9F59A42075E78EB2C7A19F8C2B034968C3EA7A64586A522604608FCA3D4F4A831D4F463D4F4240789E4A985D507E5B0E68F53D18FB35704407009147BB0E62\n"
+":40FEC0004428EA106476277109B91A2CB01C9A835752E410CA4C9A834DD4917BDC1A834769054909D4B6A51223327E2E17208FA975D0000D418E146A04CBA327D4BAE45C05\n"
+":40FF000019011F52F52006176640CA4F1A82E16C200CA4D4181653210B6580C01178341A4B932E1831EF0557977654950802DBD5F8C38D72003BB7800C097A9F6CFA9F944C\n"
+":40FF400058820605143C55C025A77FBF96CC903D0E32603817D4EEC81003978D0BC40A3240530C0E3F4A023C7916F2358C6C207ABB587A9F504D840C4EA7DC4484C5AC25FF\n"
+":40FF8000410222753EEA202225A2332184BFA4900510A1009E68063AD9C183404EF0C7A09886805FDF9625E52B21210D00B9A10FAB8EC7A9F804B031027EA7C947A767073C\n"
+":40FFC000506A30A43F21DF4582C0CC7F78E1E0440EA7D643AC73886607824EA7EE46207C301446C753871771300847E184A3A343E49C73D9C7C713A051F01C49A386C58576\n"
+":020000040802F0\n"
+":400000008AB00BAD1A40F53E99604D005B448E46C8F41301E121AD9F3A26052A23C024EA7BE5BAB8E8BA9F012EA7BC4852E9B222C3643CA7587A9AD8800147B08F0B69F035\n"
+":40004000114BCD46C412721782D3BB080951C22158F898AEA0EDBB512045AEB2B21212A487A9FE098EA69D2A9431651E5B4821822117849B47D3EFA4381016C02EA7E12A2D\n"
+":400080009F02D844EA7E34F5C20373C0847D4FCE55AA55985D62765D719641298400897DC06C3933C21792B6812D954CB69182EA7E153D39642E20A7719491EC08F9A8A03B\n"
+":4000C000B272C890083A69206E332206E102F74A5089BD4F8E3211014E23FCC935862D49209800BE2F32B688ECE9256D30B71931E5DC01AA21203A79B849A3C01A180BA060\n"
+":400100002BA9F590200BA4C8093091E5FB004AA900BC8341268E56C40D064104AE1CAD688790368017602E0FA64D479BAD0F8259875C623DCE91259F91E48CD010E8916F52\n"
+":40014000B17222791AD4B29906E5732E0EC010DAF68DF0F53DC8F54359753E38D4B8BB77BC08FAEC80AFB813AAD945D4F8CA5C726090086152D0F53EF1FA16F07D4AD25D38\n"
+":400180004FE8200F597F96CBA240496D292F233E8819B1EF0D8B846527C9FEA790200757D6664972010136FF327C202E32FC079A1C0F826EC6425AEE01CD1319018ECAC370\n"
+":4001C000CB3AEE2985315958726A10B30D9AD79C1FE77B362C1EAADE1144A768C4EA7AB7900018DE608F53D5243EE97C92008C90AFD3D9C80F3D4B9223CFA281475DF83CAC\n"
+":4002000003D8BC4A965080779F850041D22825DA034238F6E6008E3E815B1902210290043A84DE7F791E536C635F4F8910122A79DCE64F5F36D618C415F2ECD137C0435455\n"
+":400240006635866294E005BAF5290EB20B508F0090F0538885DD50FA208F590789228C84C890058843F19C30F6E3E8FA115C7AC83CC24F1F672200B6067B2A1E7AED6C4158\n"
+":400280009340538A1820009C08E0990EB2112604E484E4007D6422B0183947080C57759092006A668089D6422C80DEB056202412C4401D6420208856401D241F590888EFB3\n"
+":4002C000410E81102A88107190248F5F110E06D810CB100CB1108D10D7CC8085D94AE2209A219F95A344412C710289E26FE41418D52F0EEC1F102FC62649F9A964840F4A16\n"
+":4003000032979D0BC8F20F27F0C10406A849C9ACC79D1508023A16A071A213DC8F0051D40AF857E440B213B9DD84303C017EFFDB303345A22217BAD7841C26C14068A28389\n"
+":4003400010401A2492061176B4303C05E5C111AEE7139080010950380935480F3F550C4879B6C503FFAB8413ECBDE10489602FA4CD840B3C0040244609B011C06BC87A88AA\n"
+":40038000272211EA3E22DC870B0D905CC08753F224D8A25423E37E02077B0078EE50140000000000030000FC00000000420608A43800000370001FBF65D648086A09981AB6\n"
+":4003C00074B4D2186D202F465062BFB838A58537688636074436034ADA4EBE4F64FC797DB6CB25AEC148AE1D6768235B4A620060040100F3545BBA00102FBFB2E4030041F0\n"
+":40040000100C020480300F9540C811B8144DCA80016A248B6DB4B007A5E6080F00FA83F87B62F640105B0AC002E02007D0F3C2098060201C010080480202008C6C996F2FCA\n"
+":40044000BF7EFDFBF7EFDFBF7EFDFBF620601974D400E06010060160601B868E4110339B200D6245D64167F002004F32D54812040140581DD20A1209EF1CA20A8200B02261\n"
+":400480000B8240C6B04A7607F797DFBF7EC400003618E5F27130B09001E026C0C2D2000006000008000100020300012400000000FFFFA00038000001EC00052BFDC419401D\n"
+":4004C00012BFCC4328D10E9007900760FD308281085A802979020C02B1E2146DAD27A7C8C02E9A0414D3CF580D358868807E8EA137963594F2C0448089389F2A81C0386004\n"
+":400500005EC30AE49040E4009C0CD9821E80E73C619800F3708310E2032800BB24E981F8C6B301D00334FA186216EC055201A961B200E1EEC4098D30071ADD800D43A00322\n"
+":400540002900D25559027239F70430BE18038AF2F77D419C51C28C4095025C0A9F9398D001140026003E0D5DC089C550090035008AB1BC500B1820AA033202AC2A4608A12F\n"
+":4005800070B00FE000CB59620632C7787F0B03F202E23CE07B3870CC36407540B2807E733643243A5A366B4C410861C2D243F203B4A0420AF310A6C00247CC8223201243A7\n"
+":4005C000885880AC825C000000000000030007FC00000000FFFFAEE83800000D5C05FD551D3E1A8D909CA3C5FC2291C5DF20A30822983D13063085C020658C0FC06C884230\n"
+":40060000987D8622A214148DC08148FFA552C004291BC518110EA0A6100F5E5601928C1099CA0C853079403E9810A8086F08453880B104C4F50040A3109CC247A923E3AC93\n"
+":40064000212B8E8F30D4884C1604C1988016027086198408C2431052CC63C90401020460E43309A224190B22402608221AB8DF89E88F8200FE4442140163E62113F183FD53\n"
+":40068000A14416C301266302223C4A34480C57A46C889E131220249902718A8C61DEBF4C00C8E101807803C28F004452001C48812C8888030039A0041940511808928630BF\n"
+":4006C0008B4F0B1B50D3E1A5E2228A21046A0079418B2C0C6C6980435ADA6B124D910C510682E3831B100461456010A211430371C4C8A21A6192A885436C3B755A864005AA\n"
+":400700002024219041919120200EAA0D80E320D0AAEC85112A0CC4CA1C47ED1844E10105223800020AF218AF23A044968D6799710B04F205340895D341687028E10085215A\n"
+":40074000FA2C4B640BE895780C74B06320672F112D584847801C33010CCA5053381FC40006D60B30A950C75223D5552156442A87407785E646A510002A54D92BCD6040CC18\n"
+":40078000044EB811266319361526003500C390101A0E943C576D20095E6B46802C52807BDA789080302C43C209980D4608E157E46A6458A4C95E6D02470CB401014677384D\n"
+":4007C000C44122392370130CE3418C7C40143ACA0CDE0349903866ED9DA97B383C27D824C81E1981E850F2C5C34C1CC020326C8082A09002ED5C4314C895B57B0805586874\n"
+":4008000056990A8330058EBC0992476F042D5EDD0BDAABF36428C9FAB0E60CC28D62E5819948C8DBEC4C611E85A9922881D2238A7E782D12C8482C84E2C8542C85A2C860E4\n"
+":400840002C8662C86C245C0162830AA09FE028400B141D0A5320200A2A908029478AFE4B2BA103B0AF07B1842614683079014A58C5B90688045913A4073E211830C1631D72\n"
+":40088000C98B31A2048A280BD2C36084026C7060C586061081A0744C2200C8D30288402164210D230C03833BDA00568430300540840101A206B04AD1611A8504006882B538\n"
+":4008C000380A1DD01A24403532A312040A818080458016D2440042801D318CAD19CD8A5633F88E00206C3311006CB9289404619900121500990A4C95A4941C77DD11C5DA35\n"
+":4009000004401171DA00144A4C02C485A2240360200142093954800264C834331B2C0E191CA348024E512A636A13326C301698981C3801C0107B2050713491AD81CBFA90EE\n"
+":40094000384C05CCC89110C70048FC33604AC9E993290040D0828EBC9F18A12A148A8675C65739015E724101643A245044205A0C908463091D8B323B789DDC3686366A360F\n"
+":400980004489D80200641D0CD00641633014064102CC0D132F7C8246E64C899C9C9133C1118540EB034B550C680CC052A00231540328866A049EBE010892AC092A00929BE6\n"
+":4009C0008A314846040EA038DC029FBC19324D13FC183ECF492B174415384CC8C8BE2A9F01C4CC3FE2CFBF78C8D500810022C52388226C88162908D060D08F1C7B032050E2\n"
+":400A00002F05D29101A08C5C484AC926400213408A0460020C80219C42A4765AD136075A2A5A3D00619803902A5A790A3A71F804426011685404C0218C2155A95E8A17062A\n"
+":400A400080A668232108A0A308564032299C980144CCAFF23F6E3E314CC6CA422884EF320310280023D532968C8627F5E0C7CAC508F0883CAA118F205810B0A8E38319F8B7\n"
+":400A8000682895460199746A4CB1BBF209685645050E50523B10054B42B906C59588542800B0CE73426C2150A8441050A14E441A66AC80280042200455AEA282000C7C3D39\n"
+":400AC0004753D04A3F8BD3BCC338CAA0003D3E0573D8423F0253D8EA3A0983E4923F0253E0C53F4F43F0093D42C3E4C33ECAA3E49E3E8003F0F63D88C3E0D13EC503E852AC\n"
+":400B00003E0843F8113DCF03E103EC233EC1B3DC713F88C418E7990C7D15A7D8D27B0847F1827D0B77183C88A22F20062D87E2D88A2D8962D8A22D8AE2D8BA2D8C64E459F2\n"
+":400B4000290A401A601D6718996061008712D8080061D52E01000958BA08004B459028333211066C0063807DB9A9480112B881BD99CBC8840280D226444021003916370EEB\n"
+":400B8000B277A212D9660B1009004380AC1401E4400F10B83D0EA8A006012AC296964C5D45451B6B1B2195DAA33C1DB791F1EC1CF42A3080114B850A4212E5661B0207FCAB\n"
+":400BC0003AA1C28D3C0A3230E033028045BF51A12003768364EDC0866C80D64B0E008C361780122972A2248020065E95EDA2342366022201D9730280500A01402806BEF6A9\n"
+":400C0000F470892050F50606607B02508E1E3A5E1C46D1728255546520A205808844AE5300C015304220D92A00604240A88680E999844780013B200AC848F400E1C0451471\n"
+":400C40001003D0089CD1000D4EA4028E07B02010031CDA3A65A8458353681E43587A12C4AE38F41F88810F0381FC0C018032950844F8D5ED0C4B07D0320780EB27E13240A3\n"
+":400C80000CC9ABC4C710080A421D50102008158080C2396028200066542C6480E2030321986CE54B89803008051580E00290319DEB4F038824043529401DB8105805010870\n"
+":400CC00075816A6EA440B0C030087A28F0625510C7108B32A84CCC12056224CAE344688757CF60B360760340680D01ACB82F160F90040042C0EA964A52354702D36F27A0B7\n"
+":400D00000401739B84B6344278757C96F32E3474982A80300D58AC962E5D158155512C3817800F41A18B8DA28CBE07420B22216A229804441C0C003C5C020F50141E0044BE\n"
+":400D4000796145A362D030AEEF28A1968D4385DB032D03298AF460C4202FB068C600CD7F581A488F38326453F92CF60849032B953A82033B3F50B0BE90E06949D0B2B14D7A\n"
+":400D80006368B035B6F98A783890B8861E4EA42AA51959617601C3C862D25B1F85B80D32901859FA57046F8829F0014F348A0998C41007B7EE223E325A808896D082C1A814\n"
+":400DC000896E08460A0000000500020400000000000001F85440000671BE00A854AB0003A000A0C4A18851290002079D18F55125000201F71B7851250002050E18C8553ED2\n"
+":400E0000FFFF522F0010E619E6F2ECFAF8F2FF7904ED06A30F0E15EB169717D7197C192217A5182816FD515C0001003E005B71C60100606700024C000110605D000200006F\n"
+":400E40009C40607B0011004F0075009B00C200E8010E0134015A018001A701CD01F30219023F0266028C02B253BF00020199033370F4000070710002FF86FF8670760F33B4\n"
+":400E8000549AFEAE5058118053E900021000100054B4000C544E002850340580501A01005010F8805018FDCD53510008F000080000001000F8000266F0000333534A80004E\n"
+":400EC000537D00020000000053610008C0004000C0004000C0004000C0004000526F00080000000000000000000000000000000002990002F4F901535376F7F55348C000AD\n"
+":400F00005100115F7151002000400040004000400040004000400040FA41FC4C01520453074F0748044200400040F842F749F94DFC50FE500050064B0B400B430040004062\n"
+":400F4000004000400040004071B2522C52AA014052B30002080000A0512E2000512C010053840000539E01E0539C099952A300020000000052D2008052E500030040030075\n"
+":400F80000400533E6000538D000200008235531E0000546B000708000CCC0E660E660B330B331000545600E6545A1000545F00040700157C04000FA054680000545C00A0BC\n"
+":400FC00060110003AF80B474BC2C0000000000004953505468726561644C6F6F70006170313330325F7365745F6374726C00000020257328256429204572726F72204F637C\n"
+":4010000063757272656420696E2048414C5F4932435F536C617665527843706C7443616C6C6261636B2020537461747573203D203078253032782C20675F736C6176655FEA\n"
+":401040006E6578745F72785F6C656E203D20257520200A0D0000000020257328256429204572726F72204F6363757272656420696E2048414C5F4932435F536C6176655492\n"
+":401080007843706C7443616C6C6261636B2020737461747573203D2030782530327820675F736C6176655F6E6578745F72785F6C656E203D202575200A0D000025732825D7\n"
+":4010C000642920446562756720496E69746961746564205359534346475F4346475231203D203078253038782020464C4153482D3E4F505452203D20307825303878200A24\n"
+":401100000D00000049535054687265616400000064656661756C745461736B00496E76616C696420466F726D6174202D2030782530387820213D20307825303878202C20C5\n"
+":40114000205769647468202D2025687520213D20256875202C20486569676874202D2025687520213D20256875200A0D000000000A0D2052454144204D4173746572205402\n"
+":4011800072616E736D6974204572726F7220212120202D20307825303278203078253038782020524547203D2030782530347820666F7220736C61766520307825303278F7\n"
+":4011C000200A0D000A0D205752495445204D4173746572205472616E736D6974204572726F7220212120202D203078253032782030782530387820524547203D2030782543\n"
+":4012000030347820666F7220736C61766520307825303278200A0D000A0D204D41737465722052656365697665204572726F72202121202D2030782530327820307825300F\n"
+":40124000387820666F7220736C617665203078253032782020666F7220524547202D20307825303478200A0D000000008C12020800000020A4000000F24C00083013020884\n"
+":40128000A400002034310000024D000880841E0000000000AAAAAAAA00000000000000000000000000000000000000000000000000000000000000000000000000000000E4\n"
+":4012C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005FFFF0000000000000000000000000000EB\n"
+":30130000C0FF02080000000000000000000000000000000000000000000000000000000000000100000000000000000000000000F3\n"
+":020000040800F2\n"
+":4000000008040020D5000008C9010008C701000800000000000000000000000000000000000000000000000000000000CD0100080000000000000000CB010008CF01000893\n"
+":40004000E7000008E7000008E7000008E7000008E7000008E7000008E7000008E700000800000000E7000008E7000008E7000008E7000008E7000008E7000008E70000087F\n"
+":40008000E7000008E7000008E700000800000000E7000008E7000008E7000008E7000008E7000008E7000008E7000008E7000008E7000008E700000800000000000000001D\n"
+":4000C0000348854600F014F80048004751020008080400200448804704480047FEE7FEE7FEE7FEE7FEE7FEE7DD010008C1000008064C0125064E05E0E36807CC2B430C3CA0\n"
+":4001000098471034B442F7D3FFF7DEFFA4020008C402000810B500210748C9438162002282624162426201620262C161C26100F00DF8002010BD0000001002400248016829\n"
+":40014000491C016070470000000000207047000008B515480168821511430160C16889088900C1600168114A114001600168012212041140009101689200914301600021AD\n"
+":40018000C16042680A4B1A4005235B03D218426042681F231B029A438314D2184260016105490448086008BD00100240D4FFF6FEFF1FFF0068FF1F0004000020704710B525\n"
+":4001C000FFF7FCFF10BDFEE770477047704710B5FFF7B4FFFFF7F3FF10BD000010480168821511430160C1680E4A1140C16001680D4A1140016081684908490081600168D5\n"
+":400200000122920491430160C168FD2212049143C160002101610549C003886070470000001002400C40FF88F6FFF6FE00ED00E002E008C8121F08C1002AFAD17047704760\n"
+":40024000002001E001C1121F002AFBD17047000008B5002462B60F48009401680E4A1140C204914214D1416800910D46016881F3088872B609498860FFF76AFF08480461F9\n"
+":4002800044618461012080F31088FFF743FFA847FEE70000000400080000FE2F00ED00E000E000E0C4020008000000200800000030020008CC020008080000200004000084\n"
+":0C02C000400200080000000080841E00C6\n"
+":020000040802F0\n"
+":20FFC00031314355313331585858585858303131313035343266623436585858585858585a\n"
+":04000005080000C12E\n"
+":00000001FF\n"
diff --git a/drivers/media/platform/imx8/ecam50_cam_fw.txt b/drivers/media/platform/imx8/ecam50_cam_fw.txt
new file mode 100644
index 000000000000..79923866c34f
--- /dev/null
+++ b/drivers/media/platform/imx8/ecam50_cam_fw.txt
@@ -0,0 +1,2146 @@
+":020000040800F2\n"
+":40040000E03100204D050008013F00081F2A0008000000000000000000000000000000000000000000000000000000008D41000800000000000000000B050008014300085E\n"
+":40044000214A00085F0500085F050008ED0A00085F0500085F0500085F050008A90A0008000000005F0500085F0500085F0500085F0500085F0500085F050008F14300086F\n"
+":40048000014400085F0500085F050008000000005F050008452A00085F050008212A00085F0500087D4100085F0500085F050008114A00085F05000800000000000000009C\n"
+":4004C0000348854600F0D0F90048004781690008E0310020084B19680868203080F30988022080F31488BFF36F8F3FBCAE4608BC04BC62B6184700000C000020EFF310807A\n"
+":4005000072B6704780F310887047EFF309800E4B1A6820381060F0C044464D4656465F46F0C008B572B607F06FFA62B60CBC116808681030F0C8A046A946B246BB4680F307\n"
+":4005400009882038F0C818470C0000200448804704480047FEE7FEE7FEE7FEE7FEE7FEE79D430008C104000830B50B46014600202022012409E00D46D5409D4205D31D4627\n"
+":400580009540491B2546954040191546521E002DF1DC30BD70B500242546002801DA01244042002901DA01254942FFF7DDFFAC4200D04042002C00D0494270BDF0B51FB466\n"
+":4005C0000646002082B005464024019100901BE0019922460F46304600F0F4F8049A059B801A994110D310461946224600F0DAF8361A8F410197224601200021009F00F083\n"
+":40060000D1F838184D4100902046641E0028DFDC019B00982946324607B0F0BD03460B439B0703D009E008C9121F08C0042AFAD203E00B780370401C491C521EF9D27047F4\n"
+":40064000D2B201E00270401C491EFBD270470022F6E710B513460A4604461946FFF7F0FF204610BD0321001D401E037812021A43491EF9D510467047024670B54A40D30F88\n"
+":40068000DB0740002DD04A002AD0010E140E000212020919400A520A8418E50104465443000A120A2E045043A4194219200CC543AA18120C0125AD03521C521912047F39D1\n"
+":4006C000240400D0521C104301D44000491EC2B20C06C0092018401C4008802A02D003E0002070BD40084000002900DA0020184370BD70B502464A40D50F40004A00ED0762\n"
+":4007000040085208002814D0002A12D0C40DD30D41020120C0055202490A520AE41A091812187D34914201D3641C00E04900002C01DA002070BD0023914201D3891A0343D1\n"
+":40074000400849000028F7D100290AD0914202D10121C90705E0914201D2012101E00121C943E005C018401900F03DF870BD10B500229623114600F03EF810BD41004002CC\n"
+":400780000122400AD205090E80187F2901DA00207047962903DC9622511AC840704796398840704710B5202A04DB0146203A9140002010BD914020239C1A0346E34019433F\n"
+":4007C000904010BD10B5202A04DB0846203AD040002110BD0B46D340D0402024A21A91400843194610BD002904DA401C490001D140084000704770B40024050C05D11024EC\n"
+":40080000000402D1002921D01124050E01D100020834050F01D10001241D850F01D18000A41C002801DB4000641C002908D020252E1B0D46F540A14000D00121294308433C\n"
+":4008400001061B1B000ADB1D02D5002070BC7047DB05181880180029F8DA401C4900F5D170BC400840007047064C0125064E05E0E36807CC2B430C3C98471034B442F7D37E\n"
+":40088000FFF722FE9C160208BC16020810B5364CE069000267D4A069C007FCD16368334A334934A004F0C4F86068C00704D03C48E0603C48E06005E02C4A2D49921D3AA093\n"
+":4008C00004F0B6F86368294A29490A3241A004F0AFF8A069C007FCD16368244A2449143224A004F0A5F86068C00704D0292252011F4944A00BE06068400704D54A4860619D\n"
+":400900004A48606105E0194A19491C3248A004F08FF86368154A164922322EA004F088F84E49042003F01EFB104A114926324CA004F07EF8E2690120C005E16902434DA014\n"
+":4009400004F076F8094A0A49283245A004F070F860680121890408436060044A04492C323FA004F065F810BD002002400105000023830008202D2D2D2025732825642920ED\n"
+":40098000464C4153482D3E50454352203D2030782530387820202D2D2D200A0D00000000EFCDAB8905040302202D2D2D202573282564292050454B45595220556E6C6F63C4\n"
+":4009C0006B656420416C7265616479202D2D2D200A0D0000202D2D2D20257328256429204E6F772C20464C4153482D3E50454352203D20307825303878202D2D2D200A0D1F\n"
+":400A000000000000202D2D2D202573282564292050454C4F434B204C6F636B6564202D2D2D200A0D00000000C8D9EAFB27262524202D2D2D20257328256429204F50544C9B\n"
+":400A40004F434B20416C726561647920556E6C6F636B6564202D2D2D200A0D00F0800000202D2D2D20257328256429202D2D2D200A0D00002056616C204166746572205533\n"
+":400A80006E6C6F636B204F7074696F6E204279746573202E2E2E2030782530387820307825303878200A0D0010B50120800200F0FBF910BD04A003F0BBFF7D24E40020468F\n"
+":400AC00006F012F8FBE7000020556E7265636F76657261626C65204572726F72204F636375726564202121200A0D000010B500F02DF910BD10B5084900224A6107494B6871\n"
+":400B00004C1523434B604B68082423434B60C009C001026010BD0000A80000200020024010B5214A00219069C305204804D54169022319434161911593699B0505D5436988\n"
+":400B40000124234343616302194393695B0505D54369082423434361E301194393691B0505D543690424234343616302194393699B0405D543691024234343616302194378\n"
+":400B800093699B0304D5446920231C43446119439369DB0305D54369402423434361A0020143916110BD000000200240A800002008B517A003F03CFF00F042F91C484168FB\n"
+":400BC00042151143416041680822114341600021130619608169C907FCD18169890714D50221816141684122D2009143416018680090104A104911A003F01AFF1EA003F0BB\n"
+":400C000017FF00F011F903F09FF9FFF753FF000020466C6173682045726173652042414E4B31205374617274202121200A0D000000200240BB04000004830008202D2D2D28\n"
+":400C400020204166746572202573282564292041742041646472657373203078253038782056616C7565203D20307825303878202D2D2D200A0D000020466C617368204590\n"
+":400C8000726173652042414E4B312053756363657373202121200A0D0000000070B50024024620325179022903D00421C16301243CE001680B680E25AB430B6001680B6811\n"
+":400CC0005B085B000B601A4B0168994201D1012121E0174B1433994201D110211BE0144B2833994201D1891515E0114B3C33994201D189140FE00E4B5033994202D1012101\n"
+":400D0000090408E00A4B6433994202D10121090501E001210906064B083B59600121517100211171816B002900D08847204670BD0800024031B500F08FF9044600F08CF960\n"
+":400D40000099001B8842F9D338BD7047F8B5344CA0690026C005334D002811DBA06980050ED4A06940050BD4A069000508D4A069800405D4A069800302D4A069C00309D5CF\n"
+":400D8000287801282BD0AF68FFF7CAFE384600F055F82E70A069800712D50220A061287800280DD0287801281ED06068082188436060A868FFF7C9FF0020C043A8602E7038\n"
+":400DC000287800280AD160684121C90088436060606803210904884360602E74F8BDEF680020C043E860CFE76868401E6860686800280DD0E868FFF7A8FFE8688030E8607F\n"
+":400E000061680122520291436160FFF773FED7E70020C043E8602E70FFF797FFD0E7000000200240A800002003484168022211434160002070470000002002407047000045\n"
+":400E40000948416889070CD54168C90703D00749C1600749C16007490161074901610020704701207047000000200240EFCDAB8905040302BFAE9D8C1615141310B5012197\n"
+":400E80008902884204D1034A034904A003F0D0FD10BD000027040000ED8200082025732028256429200A0D0010B504494A69024202D04861FFF7E2FF10BD00000004014046\n"
+":400EC000F8B500230124A7E027469F403A4070D04D68022D01D0122D14D1DD08AD002D1800952D6A5E07AC46F50E0F26AE46AE406546B543AC460E697546AE4065462E4352\n"
+":400F0000009D2E624D68012D05D0022D03D0112D01D0122D16D185680326AC465D00AE46AE406546B543AC46CE687546AE4065462E43866046680D79BE43ED06ED0F9D40D7\n"
+":400F40003543456006685F000325BD40AE46AE430D79B446AE07B60FBE4065462E430660C6687546AE438D68BD403543C5604D68ED0050D52B4D6E6B26436E639E082A4D2B\n"
+":400F8000B6007519AC46AD689E07360F0F27B740BD4305273F07B84201D100271AE0234FB84201D1012715E0214FB84202D1022710E030E01F4FB84201D103270AE01E4FF4\n"
+":400FC000B84201D1042705E01C4FB84201D1052700E00627B7402F436546AF60184D2E684F689643FF0300D516432E606E684F689643BF0300D516436E60AE684F6896436F\n"
+":40100000FF0200D51643AE60EE684F689643BF0200D51643EE605B1C0A681546DD4000D052E7F8BD00100240000001400004005000080050000C005000100050001C0050CA\n"
+":401040000004014042694A4042617047002A01D0816170478162704701480068704700000400002070B5024640325378202B1CD11378012B19D00123137024245470046841\n"
+":4010800025689D432560046825681E03B5432560046825680D4325600068016819430160202050700020107070BD022070BD70B5024640325378202B1BD11378012B18D0AF\n"
+":4010C000012414702423537003681D68A5431D6005682B680F263602B3430902194329600068016821430160202050700020107070BD022070BD000010B5034A034904A0E1\n"
+":4011000003F096FC10BD000021040000D38200082025732028256429200A0D0010B5034A034904A003F084FC10BD00000D0400006F8200082025732028256429200A0D00BD\n"
+":4011400070B503689A691968D40507D50C0605D5446C01252C4344642C02DC61530508D50B0606D5436C082423434364E3010468E361920508D5090606D5416C0222114342\n"
+":40118000416411020268D161416C0B22114202D0416C01F02DFD70BD026891691268436B002B00D01847704770B5054600681449144C884213D1284600F054F80346124AB8\n"
+":4011C000124913A003F034FC6078042803D0A07860700420A07002F09BFF002068641849286888420BD1284600F03CF8064A03460F32064913A003F01BFC0320207070BD64\n"
+":401200000054004060000020F60300005982000820257328256429202D2048414C5F4932435F4572726F7243616C6C6261636B20202D20307825303878200A0D00000000E6\n"
+":4012400000780040202573202825642920457272436F6465203D20307825303878200A0D00000000406C704770B5040006D02546403568780026002802D005E0012070BD6A\n"
+":401280002E70204600F06EF924206870206801684908490001600F216068090688432168086121688A680120C00382438A60E1680129A16808D021229202114322689160FF\n"
+":4012C000E168022902D005E00143F7E701212268C902516021684A680F4B1A434A602168CA688243CA60616920690843A169090208432168C860216AE06908432168086074\n"
+":40130000206801680122114301606664202068702663AE70002070BD0080000210B5034A034904A003F084FB10BD000012040000848200082025732028256429200A0D003E\n"
+":4013400000680649884205D105480178092902D00321017070470B21FBE70000007800409000002000680649884205D105480178052902D00321017070470721FBE7000017\n"
+":401380000078004090000020F8B50546044640356878202830D120688069C04300042BD52878012828D001202870222068701020A87000266664626263851048E062104803\n"
+":4013C0006063608DFF2804D9FF20012320851B0603E0608D012320855B06092080020090208DC2B2204601F09BFF2E700221204601F07EFB0020F8BD0220F8BD0000FFFFAE\n"
+":4014000071300008FFB5054604464035687881B020287ED1287801287BD001202870FFF71BFE0746012200901923D103204601F089FF00283FD1212068701020A870002613\n"
+":40144000666403986062049860856663618D01204003FF2903D9FF222285009034E0618D2185009036E02046029901F059FF36E001F0B3FF002803D0606C042847D01AE0F8\n"
+":40148000606A411C6162017820688162608D401E6085208D401E0004000C20851FD1608D00281CD000970022802120460A9B01F049FF002802D0032005B0F0BD608DFF284C\n"
+":4014C00005D9FF222285009601231B06CBE7608D20850096208D0123C2B25B06C3E7608D0A9900283A462046C2D101F04FFF0028C2D121682020C86121684A68064B1A403E\n"
+":401500004A606870AE702E700020D5E701E00120D2E70220D0E7000000E800FE10B5034A034904A003F084FA10BD00001C040000B98200082025732028256429200A0D008B\n"
+":4015400010B5034A034904A003F072FA10BD0000170400009F8200082025732028256429200A0D00F0B5234A0168122403200125214E85B0914215D1C02100910021029193\n"
+":4015800003900194049569461C48FFF799FCB06B69050843B06300220321172000F058F9172022E0164A914221D189156A4632C20320072781C2052069460007FFF780FCA6\n"
+":4015C0001020694631C103200390694604970B48FFF776FCB06B012189070843B06300220321152000F034F9152000F027F905B0F0BD0000005400400010024000040050BB\n"
+":401600000078004038B500680D49884213D10D4CA3780A2B10D0A08900900B4A0B490C4803F006FA6078042803D0A07860700420A07002F06DFD38BD63700C20A07038BD1F\n"
+":401640000054004060000020D30300003D8200082014020838B500680E49884214D10E4CA378062B11D0A089ED22009092000B490B4803F0DDF96078042803D0A078607010\n"
+":401680000420A07002F044FD38BD63700820A07038BD000000540040600000202182000888140208F8B5034640335C78202C1ED11C78012C1BD001241C7022245C7020243E\n"
+":4016C0009C700024446405686E680127FF03BE436E6041624285418D01850649C162064941631C701F2101F003FA0020F8BD0220F8BD00000000FFFF01320008F8B503461E\n"
+":4017000040335C78202C1ED11C78012C1BD001241C7021245C7020249C700024446405686E680127FF03BE436E6041624285418D01850649C162064941631C70172101F089\n"
+":40174000D7F90020F8BD0220F8BD00000000FFFF0132000802480168491C0160704700000400002010B506480168402211430160002000F007F800F03DF8002010BD0000AC\n"
+":401780000020024000B5014687B00022102000F05FF8102000F052F81148816B02221143816305A9684600F071FA00F095FA0D49FEF7DAFE0D490C4A0A600D4A401ECA60A2\n"
+":4017C0004860002008618860084600F0EBFD002802D0012007B000BD044800F0FEFDF9E70010024040420F0000040040DC180020E703000010B51048416B012211434163FB\n"
+":40180000816B02041143816300221146501F00F01FF803210022481F00F01AF803210022081F00F015F803210022084600F010F8032000F003F810BD00100240C106C90E1F\n"
+":4018400001208840014908607047000000E100E010B502F057FB10BDF8B54E49074601250020ED034A4B4B4A4031082F7BD00EDC012F48D0022F60D0042F22D1CC68032685\n"
+":40188000B602344065D07F02BC424ED064E0102F77D00126032436042404202F09D0FF3F012F0ED1C968214053D07400A1423CD06BE00B6909692140B14203D199052EE01E\n"
+":4018C0002846F8BD01256D04A94203D19907F8D53148F8BDA142FCD111688903F9D5116803200005014001200005091A09D0091A05D0814201D12948F8BD2948F8BD294803\n"
+":40190000F8BD2948F8BDCC68A407A40F0AD0022C0BD0012C0ED0032CF4D1096989050029CEDBF8BD00F0E8F9F8BD11684907FBD51846F8BD00F0F0F9F8BDCC680C26344037\n"
+":4019400007D0082CF1D0042CF4D00C2CE5D0F8BD09E000F0C1F9FAE7012292029442E9D0B442DAD0F3E7C968032424032140F0D001256D036C10A942D7D0A142DAD0E6E733\n"
+":40198000FFE7916B4902E4D4E1E7B142D2D0DEE70024F400001002408890000020A1070000093D0040420F0080841E00F8B504460078594D800672D5574E0027403EB06B96\n"
+":4019C000C00004D4B06BA9050843B063012753480168C90511D40168821511430160FFF73BFB009005E0FFF737FB0099401A642837D84A480068C005F5D5326803210905E8\n"
+":401A000060680A400140914208D08103890F032904D13168890301D50120F8BD2A69032109040A4022D0084090421FD0207880061CD528692A6988430121C9040A432A61EC\n"
+":401A40002A698A432A612861C0050FD5FFF704FB009008E0FFF700FB0099411A3048814201D90320F8BD28698005F3D561688803800F032805D132680005824301400A4356\n"
+":401A800032602869032261681204114008432861002F04D0B16B012000078143B1632078C00705D0E868A168800880000843E8602078800705D5E8680C218843E1680843BE\n"
+":401AC000E8602078400706D5E86803218902884321690843E8602078000706D5E86803210903884361690843E8602088C00506D5E868032109048843A1690843E860207812\n"
+":401B0000000606D5E868032189048843E1690843E8600020F8BD0000401002400070004088130000F8B5054653480E460068C007C00FB0420AD250480168490849003143A7\n"
+":401B400001600068C007C00FB0426FD128784B4C800705D5E068F0218843A9680843E0602878C00752D06868022817D0032818D02168012818D08905002957DAE1688908A3\n"
+":401B800089000143E160FFF767FA69680746022912D003291CD0012926D033E021688903EAE721688901E7E74907E5E7FFF754FAC11B3348814223D8E0680007800F022806\n"
+":401BC000F4D123E0FFF748FAC11B2D48814217D8E0680007800F0328F4D117E0FFF73CFAC11B274881420BD8E0680007800F0128F4D10BE0FFF730FAC11B2148814201D947\n"
+":401C00000320F8BDE0680007800FF3D11A480168C907C90FB1420BD9016849084900314301600068C007C00FB04201D00120F8BD2878400706D5E068072109028843E96818\n"
+":401C40000843E0602878000707D5E0680721C90288432969C9000843E06000F05DF8E168084A0906090F515CC840074908600020FFF788FD0020F8BD0020024000100240D2\n"
+":401C800088130000BC8100080000002010B50F2202600C4AD3689B079B0F4360D368F02423408360D46807231B021C40C460D268D2081A40026104480068C007C00F086031\n"
+":401CC00010BD00000010024000200240014800687047000000000020044805490068C968044A4905490F515CC84070470000002000100240D5810008044805490068C96845\n"
+":401D0000044A8904490F515CC84070470000002000100240D581000810B5184AD1680C20084004280BD0082810D00C2810D050680004410F0120C003491C884010BD1068D3\n"
+":401D4000C00601D50E4810BD0E4810BD0E4810BD88020E4B000F185C0902D368890F491CDB0301D5084A05E01268D20601D5044A00E0044A5043FEF7F7FB10BD001002408D\n"
+":401D800000093D000024F40000127A00CC810008F8B504460078F24DC0074AD0E8680007800F022807D0E8680007800F032809D1E868C00306D5286880033AD56068002883\n"
+":401DC00073D036E0012062680004824203D129680143296011E0052301211B0489049A422A6802D10A432A60F1E782432A602A6802400092286888432860606800280CD06A\n"
+":401E0000FFF72AF9064604E0FFF726F9801B64287ED828688003F7D50BE0FFF71DF9064604E0FFF719F9801B6428F1D828688003F7D42078800741D5E8681F270007800F8A\n"
+":401E40003F02012807D0E8680007800F032809D1E868C00306D42868400717D5E068012823D113E0E068002817D029680922914301432960FFF7F0F8064604E0FFF7ECF892\n"
+":401E8000801B0228C4D828684007F7D568682169B84309020843686010E02868400840002860FFF7D9F8064605E090E0FFF7D4F8801B0228ACD828684007F7D42078C006A8\n"
+":401EC00076D5E868A74E0007800F0BD0A06900285DD02868FF21013108432860FFF7BCF8074644E02868800502D5A06900286ED0206A69683140884212D902F0D1F80028F4\n"
+":401F0000AED16868216AB04308436860686800E0BBE00002217F000A0906084368600FE06968B143014369606868217F0002000A090608436860206A02F0B2F800288FD19B\n"
+":401F4000206A410B0120C003491C8840E96809060A0F8549895CC840844908600020FFF711FC25E0FFF778F8C01B02288AD828688005F7D56868216AB0430843686068680A\n"
+":401F8000217F0002000A09060843686010E02968FF20013081432960FFF75EF8064604E0FFF75AF8801B02286FD828688005F7D420786F4E000723D560690028306910D0C7\n"
+":401FC000012108433061FFF747F8074605E0C5E0FFF742F8C01B022857D830698007F7D50EE0400840003061FFF736F8074604E0FFF732F8C01B022847D830698007F7D4FC\n"
+":402000002078400762D5A86B0027C00005D4A86B012109070843A863012756480168C90511D40168821511430160FFF715F8009005E0FFF711F80099401A642825D84D48FD\n"
+":402040000068C005F5D5FF20A2680130824203D131690143316111E001218902002A07D005231B029A4203D132690A433261EFE7326982433261306988433061A06800280A\n"
+":402080000FD0FEF7E9FF009007E060E0FEF7E4FF0099411A3848814259D830698005F5D50DE0FEF7D9FF009006E0FEF7D5FF0099411A314881424AD830698005F5D4002F24\n"
+":4020C00004D0A96B012000078143A963606A002842D0E9680907890F03293FD0012636060228286805D0B0432860FEF7B5FF04462FE0B0432860FEF7AFFF074604E0FEF715\n"
+":40210000ABFFC01B022822D828688001F7D4E16AA06AEA680843216BFD231B049A4311430843E860286830432860FEF795FF044604E0FEF791FF001B022808D8286880019C\n"
+":40214000F7D509E0FEF788FF001B022801D90320F8BD28688001F5D40020F8BD0120F8BD0010024000E00000BC81000800000020401002400070004088130000704738B59A\n"
+":4021800001684A68D243520609D48A68D243D20705D18A68D243520601D5816C08E04A68D243120606D48A68D243920702D4C16C884738BD4A68D2439206FAD48A68D243A6\n"
+":4021C000D20606D4426D02231A4342651022D2438A6001688A680123D2439206002A08DB426D1A4342658A6800920A684024A2430A6001688A68D243540602464032002CDF\n"
+":4022000009DB547C122C06D0446D04252C434465CC688C6800948C68E443E40505D4446D08252C4344658C680094446D002CC0D04C68E025AC434C605374FFF79FFF38BDBC\n"
+":4022400070B5040006D025464035687C0026002802D005E0012070BD2E74204600F032F80220687420680168402291430160A168606822690843E168114308436169012224\n"
+":402280000843A169520211400843E1690843216A0843A16A084321680860A0690421000C0840616A0843216848602168E06A08612068C16992009143C16166650120687420\n"
+":4022C000002070BD00B50068104985B088421AD10F48416B821411434163A02000900220019000210320039002910491052069460007FEF7E5FD002203211920FFF7A8FAD5\n"
+":402300001920FFF79BFA05B000BD00000030014000100240042204490428086902D09043086170471043FBE700E000E0094910B5401E884201D9012010BD074C606103219B\n"
+":40234000081F01F0DFFD0020A06107202061002010BD0000FFFFFF0000E000E070B502462032137D012B1BD00123137502245475046865687026B5436560046865680E68BA\n"
+":40238000354365600468A5688026B543A5600068846849680C43846053750020107570BD022070BD70B5040005D025462035687D002802D006E0012070BD002028752046AF\n"
+":4023C00000F00AF802206875211D206802F020F801206875002070BD70470268D36801210B43D360006802680A43026000207047704770B50446006801690025C9438907C1\n"
+":40240000002915DBC168C943890711D4E91E016101202075206880698007204602D0FFF7E7FF04E000F08EF8204600F025F9257520680169C943490717D4C168C943490788\n"
+":4024400013D40421C943016102202075206880698005800F204602D0FFF7CAFF04E000F071F8204600F008F9257520680169C943090716D4C168C943090712D40821C94329\n"
+":402480000161042020752068C0698007204602D0FFF7AEFF04E000F055F8204600F0ECF8257520680169C943C90617D4C168C943C90613D41021C943016108202075206872\n"
+":4024C000C0698005800F204602D0FFF791FF04E000F038F8204600F0CFF8257520680169C943C90708D1C168C943C90704D1891E0161204600F0C2F820680169C94349063F\n"
+":4025000009D4C168C943490605D44021C9430161204600F0BDF870BD00B500680121890785B088420CD101200090002002210290039001910491052069460007FEF7C0FCE3\n"
+":4025400005B000BD7047F8B5064604462036307D0D4601280DD001203075022070750427002A08D0042A16D0082A2AD00C2A4DD137E00220F8BD206801F07AFF20688169B3\n"
+":4025800008221143816120688169B943816120688169EA6812E0206801F082FF206882690121C9020A43826120688169012292029143816120688169EA681202114381613E\n"
+":4025C00024E0206801F085FF2068C26908210A43C2612068C169B943C1612068C169EA6812E0206801F090FF2068C1690122D2021143C1612068C269012189028A43C26151\n"
+":402600002068C169EA6812021143C1610120707500203075F8BD70B5040005D025462035687D002802D006E0012070BD00202875204600F00BF802206875211D206801F0EF\n"
+":40264000E7FE01206875002070BD000010B500680121890788420CD10648816B012211438163002203210F20FFF7F2F80F20FFF7E5F810BD001002407047000010B50068B5\n"
+":402680000249884201D1FFF765F810BD000400407047704770470000F8B502680446D06911680607360F07D1830605D58B0603D5204601F0F2FFF8BD95682023002E65D001\n"
+":4026C000EE07F60FFF2721370F4037435ED0C70706D0CF0504D501271762E26E3A43E266820708D5EA0706D0276802223A62E26E04273A43E266420708D5EA0706D025682E\n"
+":4027000004222A62E26E02252A43E266020709D50A461A40324305D0236808221A62E36E1343E366E26E002AC5D0800604D5880602D5204601F0B1FFE06E000703D4206831\n"
+":40274000806840061CD5204601F098FF20688168490611D5826840218A438260606E00280AD01D498163606EFEF798FA0028A2D0606E816B8847F8BD2046FFF78BFFF8BDCA\n"
+":402780002046FFF787FF0020E066F8BD2646C7026036002F0ADA6D0208D50120000510627372B3722046FFF774FFF8BD050605D50D0603D5204602F0C7F8F8BD4006FCD519\n"
+":4027C0004806FAD52046146840218C431460737200F0D3F8F8BD00006946000870B5040005D025466035687A002802D006E0012070BD00202872204600F026F824206872D0\n"
+":4028000020680168490849000160606A002802D0204601F094FE204601F07EFF0128E7D0206841680922D20291434160206881682A2291438160206801680122114301606B\n"
+":40284000204601F0E1FE70BD00B50068164987B0884227D11548C26A01210A43C262C26A0A400592C26A0A43C262C26A0A400592826B4B041A4382630C20009002200190C0\n"
+":4028800003200390042004900291052069460007FEF716FB002203211C20FEF7D9FF1C20FEF7CCFF07B000BD00440040001002407047FFB5064604466036707A83B00D469A\n"
+":4028C000202858D1002D0CD00598002809D00120A1680003814207D12069002804D1E80702D0012007B0F0BD307A012843D0012030720020E06621207072FEF7ADFB0190CC\n"
+":4029000027464037059838820598788218E0788A401E788206980090002280212046019B02F045F8002818D10120A1680003814202D12069002812D02168287888626D1C4E\n"
+":40294000788A0028E3D106980090002240212046019B02F02CF8002808D00320C2E728882168C005C00D8862AD1CE9E72020707200203072B6E70220B4E7704710B5064C8A\n"
+":40298000E178002901D000F045F8E078401EE07001F0BEFB10BD00006000002010B501684A68D243920507D48A68D243D20703D1921E8A60FFF7E2FF10BD10B504000FD099\n"
+":4029C00000F010F8E0688021084321680860616820690843A168084321684860002010BD012010BD10B50068084988420CD10848816BC21411438163002203211046FEF7BD\n"
+":402A000027FF0020FEF71AFF10BD0000002C004000100240C1680068016000207047FEE710B5074800688069172109020842044802D0FEF785FB10BDFEF7AEFB10BD00004C\n"
+":402A4000B00D002010B50648006880694005400F034802D0FEF774FB10BDFEF79DFB10BDFC0D002010B5806A01684A680123DB031A434A60826B00219163C26B9163014673\n"
+":402A800040314A78602A02D0FEF78EFB10BD20224A70FEF731FB10BDF0B503460022CE0740332824B025002E05D05E7842222746B74300D0F2228E0705D544265B78324330\n"
+":402AC0009C4300D02A434B0701D5B8231A4311238B4301D190231A4312238B4301D160210A4300680168914301600020F0BD000070B5164D1223446B002220268B43AC4270\n"
+":402B000002D0134DAC420DD14C0700D5B82211248C4301D190210A43002B11D1324340210A430DE04C0700D5B822CC0701D0F2242243890701D5F4210A43002B00D132434A\n"
+":402B40000068016811430160002070BDAD2F00089931000801688A69D243920701D400228A6200688169C943C90703D081690122114381617047F8B505460446403568784D\n"
+":402B800028218143206804D00821C16100202870F8BD8169C903CF0F8169FE230E0C81681E408A05C168920D19408C46E168022912D10621D3090E400B409E420BD1A16CB6\n"
+":402BC000491CA164A16C0229E2D10021A1640823C361297007E0664604212046FFF75CFF00202870324639462046FEF797FAF8BDF8B50026054640350446AE702C48E06202\n"
+":402C00006685606C0843606468782027282823D06878292820D068782A281DD007212046FFF73AFF6878602800D06F7026636663206801684A041F49026817D501239B033F\n"
+":402C40009A430260A06B81632E70A06BFEF726F800281DD0A06B19E003212046FFF71CFF28206870266314486063E1E7120410D502680123DB039A430260E06B81632E70B3\n"
+":402C8000E06BFEF70BF8002802D0E06B816B8847F8BD6878602804D02E702046FEF784FAF8BD6F702E702046FEF726FAF8BD00000000FFFF652A00080132000870B50446C8\n"
+":402CC0001548E062002525632022204640300646427085706563480711D52068416A606A421C62620170208D002808D0401E2085608D401E6085606C0421084360640721E8\n"
+":402D00002046FFF7C9FE21681020C86135702046FEF704FB70BD00000000FFFFF8B5064600682027C76130684268224B1A4042600025356320487563F062C80606D5316858\n"
+":402D40001020C861706C0421084370643046FFF701FF03213046FFF79FFE706C002814D134464034607860280FD06078212811D06078222808D16770A078A570402825702D\n"
+":402D8000304614D0FEF7DCFAF8BD716C3046FFF72FFFF8BD6770A078A57040282570304602D0FEF7DFFAF8BDFEF7CAFBF8BDFEF7B5FBF8BD00E800FE0000FFFF70B500254A\n"
+":402DC000064640360446B57071782020212970700BD012202063022120466563FFF75CFE35702046FEF7ACFA70BD11202063012120466563FFF750FE35702046FEF7B2FA57\n"
+":402E000070BD0000F8B50446006820260F46C66121680820C86107212046FFF73DFE20684168B20211434160206841682D4A114041602046FFF78EFE2068016825464904A6\n"
+":402E40004035002902DB0168090406D5697821292FD0E16B096849686185628D0421002A02D0626C0A4362647A070FD5426A606A431C63620270208D002807D0401E2085F7\n"
+":402E8000608D401E6085606C0843606400202063A8706063616C00290DD0616C2046FFF7A7FE6878282803D139462046FFF706FFF8BDA16BCEE7E26A0B498A4206D0E16209\n"
+":402EC0006E7028702046FEF729FAF8BD69786E7022292870204602D0FEF7BCFBF8BDFEF791FBF8BD00E800FE0000FFFF70B50026044640340546A6706178282029290ED019\n"
+":402F000061782A290AD160702220286302212846FFF7C2FD26702846FEF774FB70BD60702120286301212846FFF7B6FD26702846FEF790FB70BD0000F7B5044600680E46DA\n"
+":402F40008069C043C0062CD420272546403520688069C04380060FD5701CF8D0002E05D0FEF77AF80299401AB042F0D96F700020A87028700320FEBD21681020C861206835\n"
+":402F8000C7612046FFF7E6FD20684168064A11404160042060646F700020A87028700120FEBD0020FEBD000000E800FEF8B50546044640352878012816D001202870C80616\n"
+":402FC0000026002812DAD00610D521681020C861606C04210843606412212046FFF788FD2046FFF7B7FD3FE00220F8BD080634D5500632D520680168402291430160608DF7\n"
+":40300000002825D0206840688105608D890DFF2803D9FF202085930403E0608D012320855B060096208DC2B2204600F079F9608D218D401A6085687822282068016804D09A\n"
+":4030400001229203114301600EE00122D203F9E740212046FFF7CCFD06E0880604D5900602D52046FFF75AFE2E700020F8BD0000F8B5074604464037387815460E46012873\n"
+":4030800010D001203870F0060ED5E8060CD521681020C861606C0421084360642046FFF759FD5BE00220F8BD700708D5680706D52068416A606A421C6262017009E0B0074B\n"
+":4030C0000ED5A8070CD5606A411C6162216800788862208D401E2085608D401E60853DE02C4A30062FD568062DD5208D002825D1608D002822D0206840688105608D890D60\n"
+":40310000FF2806D9FF220020228501231B06009010E0608D2085E06A904205D000200090E36A208DC2B205E000200090208D0123C2B25B06204600F0F3F80FE020684068A0\n"
+":40314000800123D506E0700608D5680606D5608D00280ED040212046FFF74AFDB00605D5A80603D531462046FFF7D8FD00203870F8BD206841688901F0D4E16A914205D1AF\n"
+":4031800041680122920311434160E7E72046FFF715FEE3E70000FFFF10B5044640342378012B15D001232370CB0618D5D30616D5617821290ED0C16B0968496810220029A2\n"
+":4031C0000AD00168CA61416C04221143416414E0022010BD816BEFE70068C2610DE00B0705D5130703D500680821C16105E08B0603D5920601D5FFF705FE0020207010BDB5\n"
+":40320000F8B5054604464035287816460F46012811D0012028704149F8062DD5F0062BD5628D1020002A08D02168C861606C04210843606467E00220F8BDE36A012252068A\n"
+":40324000934202D0E36A934202D16A78282A08D0E26A8A4202D06978292907D02168C86151E039462046FFF729FD4CE02168C8612046FFF76FFC43E0780719D5700717D536\n"
+":40328000608D002820680BD0426A606A431C63620270208D401E2085608D401E608500E0406A608D00282ED1E06A884228D12AE0380706D5300704D539462046FFF75BFC99\n"
+":4032C00021E0B8071FD5B0071DD5608D00280CD0606A411C6162216800788862608D401E6085208D401E20850DE0216862208862E06A01210906884202D0E06A002802D18D\n"
+":403300002046FFF7F3FDB80605D5B00603D539462046FFF777FD00202870F8BD0000FFFF70B50568049C68688905890D1204044E11431943304021430143696070BD000015\n"
+":40334000009800FCF8B51C4617460E46054611E0601C0FD0002C05D0FDF77EFE0699401AA04207D92020403568700020A87028700320F8BD286881693046884304D0002052\n"
+":40338000B842E5D00020F8BD0120F9E770B516460D4604461AE0324629462046FFF7CCFD002801D0012070BD002D04D0FDF754FE801BA8420AD9616C2020014361644034E4\n"
+":4033C00060700020A0702070032070BD20688069C0438006DFD4002070BD70B516460D4604461CE0324629462046FFF7A5FD002801D0012070BD681C11D0002D04D0FDF753\n"
+":403400002BFE801BA8420AD9616C202001436164403460700020A0702070032070BD20688069C0438007DDD4002070BD94B000206946088710A908801390F8480F90002013\n"
+":4034400001251290ED03F6A001F0F2FAFC4C002202212046FDF7FAFD012211462046FDF7F5FD012003F040FB002201212046FDF7EDFD012003F038FB012202212046FDF7BF\n"
+":40348000E5FD012003F030FBC8210120019100900223EC4A0021782002F078FFEA4E040004D0EAA001F0C4FA347101E000203071E44C7822A41FE188EDA001F0B9FAF8484B\n"
+":4034C0001190E048801F807801287BD1F549F6A001F0AEFADA4C002202212046FDF7B6FD012211462046FDF7B1FD012003F0FCFA002201212046FDF7A9FD012003F0F4FA40\n"
+":40350000012202212046FDF7A1FD012003F0ECFA0020694608870EA9E94801F053FD002805D0E84ADF49E8A001F082FA48E16846008FDB4CA04203D1EAA001F079FA3FE12F\n"
+":40354000F04AF1A00F9901F073FAD54869460887FD48119902F090F90020694608870EA9D74801F02FFD00200190129800282AD02F46F64920378F427ED9481C441B2421AC\n"
+":4035800002A8FDF764F8290A684601724572DD4901982246091802A80230FDF73FF87D2040010090A01C83B202AA7821E848FDF729FF07007AD0E648FDF754FE3B46E54A52\n"
+":4035C0000090C7E01FE1002400200B900C900D9020460A21484341190A0A08AB1A735973C8490A2241180BA80230FDF717F87D20400100900C230BAA7821D548FDF702FF6B\n"
+":40360000070008D0D248FDF72DFE00903B462246A449D1A0A0E0641C652CD5D322460A204243FD208000824223D0871A3946D8A001F0FEF9B91C0BA8FDF709F8FD2080005D\n"
+":40364000C11B4819030A08AA13735073AD483A4609180BA80230FCF7E1FF7D204001BF1C0090BBB20BAA7821B948FDF7CBFE0700C8D102216A4600E01EE0914C11872046C9\n"
+":4036800002F0FAF800206A4610870EA9204601F099FC012003F028FA01201290FD20800029188DB20199081804E0FFE701250198ED030019019055E0019C0F982034844296\n"
+":4036C00025D30199441A242102A8FCF7C0FF290A6846017245728B4801992246411802A80230FCF79BFF7D204001A41C0090A3B202AA78219648FDF785FE040036D0944894\n"
+":40370000FDF7B0FD934A23461832009022E0242102A8FCF79CFF290A684601724572794801992022411802A80230FCF777FF7D2040010090222302AA78218548FDF762FEEA\n"
+":40374000019000280BD08248FDF78CFD814A019B00902E3253499EA001F06AF930E0BDB2204601940F99884200D2FEE610A8002404800146744801F025FC10A80188A24AA5\n"
+":40378000A2A001F055F9002013900EA9062001F019FC2146A7A001F04BF94149684601874748119902F068F8012003F09DF901214902A74802F060F80321A64802F05CF80C\n"
+":4037C000914813990191009010A8624A038856323449A1A001F02CF901F012FE00F03EFAABA001F025F9AF4CC821206803F0C8F91448801F8178417010218170002181804B\n"
+":40380000206803F097F90F4CA41FA078092804D10B4F00220221384646E15DE1A80D0100415031333032205468726561642043726561746564202E2E2E200A0D0000000081\n"
+":403840000004005096000020502C00202041503133303220495350202D204572726F7220434849502049442052656164200A0D004953502043484950204944203D203078E2\n"
+":403880002530347820616E6420536C6176652041646472203D20307825303278200A0D00FFFF000000140208257320456E746572656420546872656164202E2E200A0D00DD\n"
+":4038C0000260000027040000257328256429204572726F7220696E20493243202121200A0D0000000A0D20536B697070696E6720426F6F742044617461202E2E2E200A0D86\n"
+":4039000000000000580601080A20312E20496E697469616C20426F6F7420446174612053697A65203D2030782530347820426173652041646472657373203D203078253083\n"
+":403940003878200A0D00000052F00000FF9F0000FC0D00203B0500000A0D25733A2025642E204661696C656420746F206C6F616420706C6C5F696E69745F64617461202D6E\n"
+":4039800020256420307825303878200A0D2000002057726974696E672052656D61696E696E6720504C4C202D20307825303478204279746573202D205772697474656E20BD\n"
+":4039C000307825303478204279746573200A0D000A0D25733A25643A204661696C656420746F206C6F6164206932635F626F6F745F64617461202D20256420307825303877\n"
+":403A000078200A0D20000000F92800000A0D20426F6F74204441544120435243203D20307825303478203C3D3E20307825303478200A0D000A0D20426F6F74205374617415\n"
+":403A40007573203D20307825303478200A0D00001E5000000C1000000A0D20257328293A256420435243203D20307825303478203D3D203078253034782C2020535441546B\n"
+":403A80005553203D20307825303478200A0D0000537461746520636F6D706C6574650A0D0000000084000020FDF7D0FA012211463846FDF7CBFA022003F016F80020504F7B\n"
+":403AC000B071C821386803F05BF8A07860701220A070386803F02EF8A07802280DD10020474FF071C821386803F04AF8A07860701020A070386803F01DF8A07803280DD10D\n"
+":403B000000203F4F3072C821386803F039F8A07860701020A070386803F00CF8A07804280ED101F047FD364F7072C821386803F027F8A07860701020A070386802F0FAFFBC\n"
+":403B4000A07805280ED101F063FA2D4F7074C821386803F015F8A07860701020A070386802F0E8FFA07806281CD100200121254A00900191137A51887820121D02F006FC22\n"
+":403B8000070002D020A000F053FFF7741C4FC821386802F0F5FFA07860701020A070386802F0C8FFA078072813D11FA000F040FF022002F099FF0020114F7075C8213868B1\n"
+":403BC00002F0DEFFA07860701120A070386802F0B1FFA078082800D073E41AA000F028FF0020074FB075C821386802F0C9FFA07860701020A070386802F09CFF61E40000D3\n"
+":403C00008400002014190020204572726F722052656769737465722052656164204572726F72200A0D00000020506F776572696E6720446F776E20495350202E2E2E200A04\n"
+":403C40000D0000002057616B696E6720557020495350202E2E2E200A0D00000010B508210148FDF7EFF910BD00040050F0B5274887B0C16A01242143C162C16A214005916C\n"
+":403C8000C26A02210A43C262C06A002508400590202000900195694602951D48FDF710F91020052703263F07009001946946039602943846FDF704F9019400966946144897\n"
+":403CC00003960294FDF7FCF8012210213846FDF7BDF9002202210E48FDF7B8F9012211460B48FDF7B3F9A00200900A480190694602953846FDF7E4F8002203210720FDF77A\n"
+":403D0000A7FD0720FDF79AFD07B0F0BD00100240000400500000111010B512481049016011494160842181600121C1600021016141618161C1610162FDF796FA00280BD151\n"
+":403D400000210848FDF78EF9002805D100210548FDF7ADF9002801D0FCF7ACFE10BD000000540040B00D00202A12B00010B511480F490160104941600021816001614161BA\n"
+":403D800081610122C161C2600162FDF76DFA00280BD100210748FDF765F9002805D100210448FDF784F9002801D0FCF783FE10BD00780040FC0D0020330F600010B50F4881\n"
+":403DC0000D490160FF21053141600021816002220261C16001224261C161016252024162826181620721C162FEF72AFA002801D0FCF760FE10BD000000300140480E002001\n"
+":403E000010B5164A164886B0910706C02021016000241E21846041600838FEF7FCFB002814D1049404A90E480594FEF797FA00280CD16020009004200190039000226946C0\n"
+":403E400002940748FEF77FFB002801D0FCF732FE0348FEF761FB06B010BD000055D00000A00E002010B50C480A490160E1214902416000218160C16001618161C1610C224E\n"
+":403E8000016242614162FEF7A9FC002801D0FCF711FE10BD00440040D80E002010B50CA000F0C6FD0F480E490160FF21813141607F218160C160012149020161FEF77DFDE7\n"
+":403EC000002801D0FCF7F6FD07A000F0B1FD10BD20494E49542057574447200A0D000000002C0040480F002020494E495420575744472053554343455353200A0D000000ED\n"
+":403F0000704700008307FF22DB0E9A408907090E994000280BDA0007000F0838830808489B001818C36993430B43C3617047830804489B001B181868904308431860704736\n"
+":403F400000ED00E000E400E0BFF34F8F04490348C860BFF34F8F00BFFDE700000400FA0500ED00E038B50D461A494418206800902346194A19491AA000F05AFDE8430004E8\n"
+":403F8000284320602068144A00902346521D134922A000F04DFD2E4CA069C007FCD10E4A0E490D322BA000F043FDA069800702D50220A06105E0084A084914322AA000F05E\n"
+":403FC00037FD4F22120105492EA000F031FD002038BD00000000F81FD904000014830008202D2D2D20204265666F7265202573282564292041742041646472657373203050\n"
+":4040000078253038782056616C7565203D20307825303878202D2D2D200A0D00202D2D2D202573282564292041742041646472657373203078253038782056616C756520E0\n"
+":404040003D20307825303878202D2D2D200A0D0000200240202D2D2D20257328256429202D2D2D200A0D0000202D2D2D204552524F52202D20257328256429202D2D2D20E8\n"
+":404080000A0D0000202D2D2D205355434345535320257328256429202D2D2D200A0D000070B517490023CA681206120F18D18A6B154CD500134A02D51268224009E08E6B80\n"
+":4040C00001252D072E438E6312688E6B2240AE438E63A24204D103218903884200D101230A48016849084900194301600068C007C00F984201D0012070BD002070BD0000CF\n"
+":404100000010024000700040001800000020024070B512A000F08CFC154D28680168490849000160286800248462286844624B2149011048FCF78BFA0F4805210482818103\n"
+":4041400041818471FF210171417129680A6801231A430A6081784170847070BD524553455420534C41564520493243200A0D0000B00D00205C0F00206000002010B5024861\n"
+":40418000FDF7FDFF10BD0000480E00207047000030A000F04DFC0025344C0426A078042801D1FFF7B5FFA289002A04D0A078082805D00C2803D0A078002802D010E060705E\n"
+":4041C000A5706281A58165700A20A07028492948FDF768FA002803D027A000F029FC2EE0A0780C2804D008282DD1A08900282AD11E4B61890C331A1D1D4801F07BFD00281C\n"
+":4042000008D06922D200284928A000F011FC3348208111E0228A002A15D0E2812582A07860700620A07012491248FDF767FA002809D02BA000F0FCFB60780428AED0A078CC\n"
+":404240006070A670AAE70520E07009481438FEF7E1FBA3E720456E746572656420736C617665207468726561640A0D00600000205C0F0020B00D00204572726F72204F63C5\n"
+":4042800063757272656420696E2048414C5F4932435F536C6176655F526563656976655F4954200A0D0000001082000820257328256429204572726F72206F6363757265CA\n"
+":4042C00064206F6E20686F73745F6672616D65776F726B202121200A0D00000008200000204572726F72204F63637572726564206174205472616E736D6974200A0D000072\n"
+":4043000010B502F071FC10BD10B523489AB001680322D2029143C21489180160012102200391102100900491099040040B90000100240C900A946846FDF72AFD002817D126\n"
+":404340000F20159003201690179418940121199415A8FDF7E7FB00280AD1FF200B3012940D90109413940DA8FDF720FB002801D0FCF7A0FBFDF7AAFC7D21C900FCF7F4F8D1\n"
+":40438000FDF7D4FF0420FDF7C5FF03210022081FFDF75EFA1AB010BD0070004010480168821511430160C1680E4A1140C16001680D4A11400160816849084900816001681B\n"
+":4043C0000122920491430160C168FD2212049143C160002101610549C003886070470000001002400C40FF88F6FFF6FE00ED00E010B50248FDF7FDFF10BD0000A00E0020D4\n"
+":4044000010B50248FDF7F5FF10BD0000DC180020F0B502680124A407124D134E134FA04205D0A84203D0B04201D0B84204D11346702293434A681A43A04205D0A84203D059\n"
+":40444000B04201D0B84204D103231B029A43CB681A4302608A68C2620968816201214161F0BD000000040040000801400014014030B5026A520852000262026A4568836975\n"
+":404480007024A3439C080B68A40023430224A2438C6845601443836149684163046230BD30B5026A10239A430262036A4568826973242402A2430C68240214432022934365\n"
+":4044C0008A68456012011A43846149688163026230BD30B5026AFF2301339A430262026A4568C3697024A3439C080B68A400234301246402A2438C68456024021443C36178\n"
+":404500004968C163046230BD30B5026A01231B039A430262036A4568C26973242402A2430C68240214430122520393438A68456012031A43C46149680164026230BD10B5FF\n"
+":40454000818CC90707D001684A6801235B049A43836A1A434A60818C890707D501684A6801231B049A43C36A1A434A60818C490707D501684A6801239B049A43036B1A4371\n"
+":404580004A60818C090707D501684A680123DB039A43436B1A434A60818CC90607D50268916801231B039943836B19439160818C890607D501688A6801235B039A43C36BD5\n"
+":4045C0001A438A60818C490612D503685A6801210905046C8A4322435A60026C8A4207D10268516803235B059943436C19435160818C090607D501684A680123DB04806C23\n"
+":404600009A4302434A6010BDF8B500260446C666FCF722FD054620680068124F000709D501212B46002249052046009700F0BFF900280DD12068006840070BD501212B46AD\n"
+":40464000002289052046009700F0B1F9002801D00320F8BD202060346072A07226720020F8BD0000FFFFFF0110B5806A0022014640314A834A82FEF70DF810BD01680A683B\n"
+":40468000FF2321339A430A6001688A68520852008A60202160308172704770B50246403201466031938B8D7A0C460168222D05D08869082210438861022070BD496A012696\n"
+":4046C0008568360389B2B54202D10569002D0BD01940436D5D1C45651970518B491E0904090C518307D015E0456D19402980416D891C4165F1E701680A68FF2321339A43AC\n"
+":404700000A6001688A68520852008A602021A172FEF7CEF8002070BDFEB50446016880682269E36910436269102700261A4310430A683546784B1A4002430A602068416888\n"
+":40474000032212039143E26811434160734A2168A069914201D0226A10438A680B231B029A4302438A606E4A20686E4990420CD1C8688007800F06D0012843D002283FD09A\n"
+":40478000032826D124E0012723E0674A90420AD1C8680C21084031D0042833D008282FD00C2816D114E0614A904227D0604A904224D05A4A90420CD1C968032080020140E9\n"
+":4047C0001CD01015091A1DD0091A19D0814200D108270220FDF740F80190504B514922684039D81300929A4235D1002F0CD0022F0DD0042F12D0082F1CD113E00027E8E718\n"
+":404800000227E6E70427E4E7FDF766FA08E00868C00601D5474805E0474803E0FDF77CFA002873D0626851005118814202D81103814201D2012569E0010E060250080023BD\n"
+":4048400030185941FBF7BAFE032109023B4A411A914259D9EEE7E26982422DD13B0000F0F7F80906080B24192424241F2400019812E0FDF741FA0FE008686168C00602D50F\n"
+":4048800048082F4A01E02F4A48088018FBF76CFE86B20BE0FDF740FA616840004A08F4E76168012248081204EFE70125310909013007400F084327E03B0000F0C9F80907A4\n"
+":4048C0000A0D061D060606290600B3E7FDF704FA14E0FDF711FA11E008686168C00602D54A08144801E014484A081018FBF73CFE81B20098C16009E0FDF70EFA61684A087A\n"
+":404900008018FBF731FE80B22168C8602846FEBD61684A08E9E70000F369FFEF00480040003801404010024000440040004C00400050004000093D000024F400FFFC0F00E2\n"
+":4049400000127A000048E8016921095C212901D00220704702464032518A002912D0012381681B03994202D10169002915D0C16C4B1CC364006809788162508A401E508215\n"
+":404980000020704701680A6880239A430A6000680168402211430160F2E7C16C03680988C905C90D9962C16C891CC164E5E7FFB581B017460E4604460A9D1DE0681C1BD01C\n"
+":4049C000002D05D0FCF748FB0499401AA84213D920680168FF22A1329143016020688168490849008160202060346072A07200202072032005B0F0BD2068C16930468843CA\n"
+":404A000004D00020B842D9D00020F3E70120F9E710B50248FDF740FE10BD0000D80E002010B50248FDF7BAFF10BD0000480F00200FB410B503A9044B044A029800F024F859\n"
+":404A400010BC08BC04B01847D95C0008A400002030B47446641E2578641CAB4200D21D46635D5B00E31830BC184702E008C8121F08C1002AFAD170477047002001E001C100\n"
+":404A8000121F002AFBD17047FFB591B00F460546002606E025280AD0149A139990476D1C761C28780028F5D1304615B0F0BD002400940121F34A029400E004436D1C2B788E\n"
+":404AC0000846203B98401042F7D128782A280ED0022128780246303A092A15D8009A0A235A43303A80180C436D1C0090F1E701CF0090002805DA01204003044300984042E4\n"
+":404B00000090022004436D1C28782E2815D10420044368786D1C2A280AD101CF6D1C02900BE002990A225143303940186D1C02902878014630390929F3D928786C2810D0A7\n"
+":404B400006DC4C281AD068280ED06A2817D104E0742813D07A2812D110E00120400504430CE00121090501E0032109050C436978814203D10120000524186D1C6D1C28787E\n"
+":404B800003906E281ED00CDC632831D004DC00288AD0582811D1B2E064287BD069280CD178E073282DD004DC6F2870D0702804D1A7E075286CD078286BD0149A139990474F\n"
+":404BC000761C62E06002400F022807D003280AD0042838680AD006603F1D56E03868F11706604160F8E738680680F5E70670F3E73878694608740020487404A80390012095\n"
+":404C000003E0386803900020C0433F1D61070FD5002101E00199491C029A0191914213DA8142F7DB019A0399895C0029F2D10BE0002101E00199491C01918142FADB019A56\n"
+":404C40000399895C0029F5D101990098139A401A00902146149B00F03BF901998019461807E0039803990078491C0391149A139990470198401E0190401CF2D12146149BB3\n"
+":404C8000139A009800F014F986196D1C09E741E033E034E00A200021049005916002410F022905D001CFC2179446032905D007E0FF1DFF08FF0003CF06E000B2C217944681\n"
+":404CC000042902D140B2C1178C4600226146944506DA0A460021404291418C462D2102E0210504D52B216A461176012103E0E10701D02021F7E7019154E00A200BE0102065\n"
+":404D000009E01020049000210420044308200591029003E008200021059104906002410F022905D001CF00229446032906D006E0FF1DFF08FF0003CF8C4603E080B2042926\n"
+":404D400000D1C0B20021019121072BD50399702906D0049A1021059B4A401A4305D00EE040216A461176012108E06146014306D030216A4611760399517602210191049A50\n"
+":404D80000821059B4A401A430CD16146014301D1610707D530216A461176012101910299491E02910399582904D037A103910FA90F910DE039A1F9E76146059B049AFBF761\n"
+":404DC000FDFB039B8C469B5C0F9A521E0F92137061460143F0D10F9807A9081A20300390600704D5012000048443029801E0012002900399884201DD401A00E000204118BE\n"
+":404E00000290019809180098401A0090E00306D42146149B139A009800F05AF886190020049008E006A9085C149A139990470498401C761C049001998842F3DBE0030CD5B7\n"
+":404E40002146149B139A009800F042F8861904E0149A302013999047761C0299481E02900029F5DC08E00F980F990078491C0F91149A13999047761C0399481E0390002955\n"
+":404E8000F1DCFBE60928010030313233343536373839616263646566000000003031323334353637383941424344454600000000F8B5044600251E461746880404D405E0E8\n"
+":404EC00039462020B0476D1C641EF9D52846F8BDFFB50446002581B01E46C80301D5302700E02027880404D505E038460399B0476D1C641EF9D5284605B0F0BD70B50D46AD\n"
+":404F0000002812D001780446432903D015A0FFF78FFD0AE00221A01C00F0C8FE21790246914204D017A0FFF783FD022070BD22480178052901D0214A1170617801706188A9\n"
+":404F40000802090A084381B2012901D9012100E000214018801C2880194901200870002070BD000020496E76616C6964205369676E617475726520307825303278202121A9\n"
+":404F8000200A0D0020476976656E2020435243203D2030782530327820213D2043616C63756C6174656420435243203D20307825303278200A0D0000650000206400002079\n"
+":404FC000660000207CB50546C8220120019200900A4602232946782001F0D8F9041E04D0294602A0FFF724FD20467CBD204572726F722052656164696E6720726567697348\n"
+":40500000746572202578202121200A0D00000000FEB5CF4E0021B08D6A4691800D22920103465343CC4CCB4FCB4A1C19D2583B46396825791B79914201D1AB4204D0C7A078\n"
+":405040000095FFF7F5FC80E1012B0BD1B968E268914202DCA368994206DAD0A0A368FFF7E7FC72E10920FEBD7821F0854843841920460A467C30B749FBF7D0FACD4BE26F21\n"
+":40508000B348D11A40309A4277D021DCCA48B04D111A2035824265D00FDCC849501A8A4249D005DCC64810182DD0012826D136E00A287AD00E2821D160E00227C14801291D\n"
+":4050C00074D0022973D0072972D0082916D13DE09F4D603523296CD008DC01296AD0072969D0082968D00C2908D1F2E025296ED029296DD02C296CD030296BD0B249B3A0C6\n"
+":40510000FFF796FCAEE7803420790102684681800720000300F0B0FB2079687413E1803420794006410C68468180AE4800F0A4FB2079A87407E18034207901026846818075\n"
+":40514000A94800F099FB2079E874FCE080342079010268468180A4480A3000F08DFB20792875F0E0803420790102684681809F4800F082FB20796875E5E075E0803464212A\n"
+":405180006068FBF707FA0007050C08036421FBF701FA0105090D2943684681809248001D00F06AFBA088F086CDE006E03FE020E014E078E05FE092E097E0803460680028B4\n"
+":4051C00009D08B496846818051200002B7E05FE0A2E08EE06BE086490839F3E78034A08881B268468180834800F046FBA0887087A9E001A90646FFF7E5FE80346068002810\n"
+":4052000002D001280BD104E0694688883843888005E068468088C107C90F6846818068468188304600F028FB207928778BE001A90646FFF7C7FE80346068002802D0012854\n"
+":405240000AD105E06946888801210843694602E0694688883840888068468188304600F00BFB207968776EE0803421798177606800F064FB67E0817F012903D08034A1880B\n"
+":40528000018460E08034A188018400F03BFC5AE0807F022859D1803460687066A978606800F0D8FB4FE080342079A8704BE080345148616800F010FB50486168FBF76AF98F\n"
+":4052C0000006010C4C48801F00F0D6FA6068F06639E080346068306400F0D2FC02E080346068706400F04CFC2DE080346068B064F8E780346068072801DD083800E00830DC\n"
+":40530000000369468880684681883748801D00F0B3FA6068306716E080346168022914D8334E2736002903D18021304600F0A4FA6068022801D0002803D18121304600F013\n"
+":405340009BFA207928760020FEBD0220FEBD000014190020642D0020588400080A0D204374726C2049442030782530387820213D20307825303878206F72204374726C2060\n"
+":40538000547970652030782530327820213D20307825303278200A0D000000000A0A0D202564203E20256420203C202564200A0A0D00000001099A001309980002099800D6\n"
+":4053C00000F767FF0C1000000E14020825733A20756E6B6E6F776E206374726C2069642E0A0D0000DA52000006700000065000005F1100000A5100002820000040420F0063\n"
+":40540000F0B585B000206946039008810A240125042303AAD82178200095019400F0B6FF34A00399FFF704FB39483A4F007C002801D0142100E01221384600F01DFA3548F1\n"
+":4054400001211C3800F018FA324830211E3800F013FA012605217603C901304600F00CFAFF21E131B01C00F007FA2A480F218902103800F001FA2849284800F0FDF931460D\n"
+":40548000701000F0F9F9042303AA682178200095019400F07BFF22A00399FFF7C9FA02A90620FFF78FFD6846018926A0FFF7C0FA02A92B48FFF786FD6846018929A0FFF75B\n"
+":4054C000B7FA274802A9801CFFF77CFD684601892BA0FFF7ADFA02A93846FFF773FD684601892EA0FFF7A4FA00F066FC002005B0F0BD00000A0D204C696E652074696D65AB\n"
+":40550000203D20307825303478200A0D000000003419002030200000FF0F0000465000000A0D2048494E46204D495049204672657175656E6379203D2030782530347820EA\n"
+":405540000A0D00000A0D20426F6F7420537461747573203D20307825303478200A0D000038600000204146204D49504920436C6B204D53423A203078253034780A0D000064\n"
+":40558000204146204D49504920436C6B204C53423A203078253034780A0D0000204D495049204C616E6573203A203078253034780A0D0000FEB5704C704F20462038028D89\n"
+":4055C00018204243BE68FD6839683869237C7F68002BBC4630D06A4B9A582346203B1F8D18235F439646664B31E0DF88BE4235D0D8889A8800920290634601967246614829\n"
+":40560000FFF716FA16E059898D4202D1998988422AD05DA00CE0D9898D4223D859898D4220D3198A884202D8998988421CD25EA0FFF7FEF90220FEBD514B90339A584E4B78\n"
+":405640009646203B1F8D18235F434D4B9033FB187145CDD19F88BC45CAD1C6E7197A0129D9D1D0E759A0E3E74348142243491438FAF7D4FF404D5E48203DE968C1421BD12A\n"
+":4056800030215C4800F0F8F80F262969F6017F228F1B0123D2055848B1425CD0574E0FDC8F1B17D0B7420FD12D2669693601891B15D0F0291ED118E051A0FFF7B9F907E0F3\n"
+":4056C000BE1B4ED0202E52D057A06A69FFF7B0F90920FEBDC26002616B84002009E05C49C26001616B84237004E0C26002616B84022020703F480121801C00F0BDF80124B5\n"
+":40570000640366102146304600F0B6F8287E0006010C38480E3000F0AFF8288A81B2204600F0AAF8A88A81B2A01C00F0A5F800F0A7FA00F025FA10482030807F00F0FEF84B\n"
+":4057400044A06A692969FFF773F92146304600F093F80020FEBD3E49C26001616B840320C7E73B49C26001616B840420C1E7C26002616B840520BCE734190020502D002077\n"
+":40578000388300084C150208496E76616C6964204672616D652052617465202D2044495343200A0D00000000496E76616C6964204672616D652052617465202D20434F4EAB\n"
+":4057C00054206D696E200A0D00000000496E76616C6964204672616D652052617465202D20434F4E54206D6178200A0D00000000ABA6A9A6122000009000002080020000FA\n"
+":405800005468697320666F726D617420307825303878206973206E6F7420737570706F72746564200A0D000020576964746820256420486569676874202564206973206E3B\n"
+":405840006F7420737570706F72746564200A0D00BE9FAA3F204368616E676564204672616D652053697A6520746F2025642078202564200A0D0000003EB5044668460181A1\n"
+":40588000C821002001910090022302AA2146782000F07CFD030005D068460289214602A0FFF7C6F800203EBD4572726F722057726974696E6720726567202578203D2030C5\n"
+":4058C00078253034782020657272203D20307825303278200A0D00003EB505460291C821002001910090042302AA2946782000F04DFD040007D00346294604A0029AFFF772\n"
+":4059000097F820463EBD00203EBD00004572726F722057726974696E6720726567202578203D203078253034782020657272203D20307825303278200A0D0000FEB5074629\n"
+":4059400000253948394C3A4E0295002F04D0022F02D0012F53D065E02C21FFF78DFF40212046FFF789FF304800213430FFF784FF2D4800213630FFF77FFF01242A48A40307\n"
+":4059800021463830FFF778FF274821463A30FFF773FF284C022F05D1204660308178606E00F058F823482449203000780300FFF74FF806041E04202224081D48001FFFF797\n"
+":4059C0008BFFE06E02900A200190042302AA31460095782000F0DAFC1848E16EFAF7C4FD0006010C1248801FFFF746FF1AE01449E3E71449E1E71449DFE71449DDE72021D2\n"
+":405A0000FFF73AFF00212046FFF736FF104C08482146001FFFF760FF21463046FFF75CFF00F070F80020FEBD02500000E452000028200000141900201534000040420F00A6\n"
+":405A4000102700004D3A0000CB660000828B0000B08F0600F8B50C462749884249D80104264F0E0EC5B269463846FFF7ABFA694608887911084381B23846FFF7FDFEB60842\n"
+":405A80006408301B00B269460880002800DA002008800006010C1A48FFF7EEFEAD08281B00B269460880002800DA002008800006010C1348801CFFF7DFFE301900B2694633\n"
+":405AC0000880402800DD402008800006010C0C48001DFFF7D1FE281900B269460880402800DD402008800006010C0548801DFFF7C3FE0020F8BD0000FFFF0000102000009A\n"
+":405B0000365000007FB5002419480394008C642148430A250290042302AA164901950094782000F033FC042302AA134978200195009400F02BFC01200090042303AAE82189\n"
+":405B40000195782000F022FC0C480299FAF70CFD074940398969814200D208460006010C05480838FFF788FE002004B070BD0000541900200C5000002820000040420F0083\n"
+":405B8000F8B53B48006CFAF7F2FD3A4D00908D270446FF053846E968FAF7ABFD3649FAF76BFD2146FAF7A5FDFAF7E8FD304C06B24034E68138462969FAF79BFD2E49FAF730\n"
+":405BC0005BFD0099FAF795FDFAF7D8FD05B228482582E121406C0901FAF7DCFC074601208003FF21801B6931FAF7D4FC01460120794340030F181E48A781E121806C090101\n"
+":405C0000FAF7C8FC009001208003FF21401B6931FAF7C0FC60820099484301214903081AF10F891949107A1AA082E282EA0F52195210831A6383791821838018A083E18A6A\n"
+":405C40000E48FFF719FE0D48618B801CFFF714FE0A48218B001DFFF70FFE0848A18B801DFFF70AFE0A2000F03FFF0020F8BD000014190020900000200000C842042000004F\n"
+":405C800009481921027849012038012A06D1026C1346FF3B0D3B01D1521C0264026C8A4200D9016400207047341900200346002010B50246002B05D0002903D04B2464014A\n"
+":405CC000A14205D9002010BD9C5C6040521C92B28A42F9D310BD000013B5044B012269460348FCF7E6FD00981CBD0000FFFF0000D80E0020F8B51D461446002825D0002918\n"
+":405D000023D0002C21D04B267601052903D1114A1278002A09D0224600F08AFF07000ED00DA0FEF785FE3846F8BD1946FFF7E6F8070001D012A0F4E70020208002E0208881\n"
+":405D4000B04202D82888B04201D90220F8BD0020F8BD0000660000204572726F72206F6363757272656420696E2070726F636573735F636F6D6D616E64200A0D000000009D\n"
+":405D80004572726F72206F6363757272656420696E20616E616C797A655F6C656E6774685F7061636B6574200A0D0000EFF30580002800D001207047F0B5304A0024547426\n"
+":405DC0000A2090741020D0741075012513465575DC20203BD8866A20186415762848588721461177104651772030FF26817739360684064620363176224F5F661827B77046\n"
+":405E00005964214FDF66996408271F670B2711703F045F626F038781C182AB03038341838383C381038241828782F576174E40380D21234689014B437821F7586143091893\n"
+":405E4000CF679B191F7980310F70012F12D01F7A0F72DB68CB60641C282CE9D3167C0C4C0521FF22C901E132C4604B2310302EC00020F0BD1B694B60EDE70000341900203B\n"
+":405E80009411000080800000E02202005884000855595659002808D00C490D4A8978002905D00320D0750020704702207047417803780802184341BA06480023022903D032\n"
+":405EC00001210174D375EEE70374FBE790000020502C00203419002070B5104CA078102808D00F49112814D0122814D001208871002070BD0B4D0121286800F041FE0028D8\n"
+":405F000001D0012070BD0920A070286800F012FEEEE70320EBE70820E9E7000090000020502C002084000020FEB500220446684602811646002907D003200880002C41D033\n"
+":405F40002578FF2D02D004E00220FEBD1E48057825701E498878FF280CD00F23002822D0122820D0F027112820D0C00621D46770A27022E0164869460881012000900190AF\n"
+":405F8000022302AA0621782000F000FA060003D010A0FEF74DFD15E068460089000A60706846008908E06370F12005E06370A77003E08888010A6170A0700E48405D0028CD\n"
+":405FC00000D006463046FEBD6400002090000020F10F0000204572726F722052656769737465722052656164204572726F72200A0D000000502C002030B500290AD0244BA1\n"
+":406000009B78102B0CD02348D90605D401210174084630BD022030BD03210174084630BD0025282802D30D800A2030BD78235843194BC318184680300478012C02D0022C44\n"
+":4060400015D001E009240C80002A1ED0D96F090E1170D96F090C5170D96F090A9170D96FD170017811710178012903D00DE00D80092030BD4168090E51714168090C917163\n"
+":406080008188090AD17100791072002030BD000090000020502C00201419002070B50024002905D0282805D3002008800A2070BD022070BD0D239B01344D584343191E7949\n"
+":4060C000012E02D0022E05D101E0152601E09E890A360E80002A56D02958090E11702958090C5170295A090A9170285CD070187910711879012802D0022844D12CE09868A3\n"
+":40610000000E50719868000C90711889000AD071187A1072D868000E5072D868000C90729889000AD072187B10731869000E50731869000C9073188A000AD073187C1074B9\n"
+":406140005869000E50745869000C9074988A000AD074187D107516E0187A5071D868000E9071D868000CD0719889000A1072187B507205E0181920301119007C8872641C84\n"
+":40618000D868A042F6D8002070BD000058840008F8B500271646002905D0282805D3002008800A20F8BD0220F8BD0D22920150431E4A851828792C46A034012802D00228A4\n"
+":4061C00009D11CE0207E032801D0232002E0A07E400124300880002E25D02946983120223046FAF71BFA3046217E2030017000214170617E8170217E032905D013E0A8897A\n"
+":406200000A3008800920F8BDA17EC17008E078012918801920222430BB31FAF7FFF97F1CA07EB842F3DC0020F8BD0000588400087CB50024054600291ED002200880002DFF\n"
+":4062400018D0C82101200191009002230B4A0021782000F09BF8040004D009A0FEF7E8FB0D484470054E0DA0B61FF188FEF7E0FBF088288020467CBD02207CBD9600002004\n"
+":406280004572726F72204348495020494420526561640A0D00000000502C002043484950204944203D20307825303478200A0D0030B500290AD0334B18241D7C0023444381\n"
+":4062C000002D28D0062828D22F482BE0022030BD0D2500E015250D80002A51D00159090E11700159090C5170015B090A9170005DD0709888000A107118795071D888000A06\n"
+":4063000090719879D071187A1072187A01280ED0022835D116E0062802D30B800A2030BD1948903023181D7A012DD3D1D0E75889000A5072987A90729889000AD072187B55\n"
+":4063400010731DE05889000A5072987A90729889000AD072187B1073D889000A5073987B9073188A000AD073187C1074588A000A5074987C9074988A000AD074187D1075BC\n"
+":40638000002030BD3419002038830008FFB585B01D460E980F9B14460E4601280DD8042D0BD8002C09D0604A00215164320AF1B2002872D0012860D102E0022009B0F0BDA2\n"
+":4063C0006846027141710093022301AA56480599FBF718F807001FD05348FAF743FF0446059800903346224639465048FEF720FB4D4D28680168490849000160012000F047\n"
+":4064000073FB286801680122114301601EE0042C7ED0032F7CD081E000200190029003904348092101702B4601AA3F480599FAF7ABFF07000DD03C48FAF714FF044600969E\n"
+":40644000024639463B48059BFEF7F2FA202C67D0DDE700F0E8FB364E02E0012000F044FB30780928F9D0012D04D0022D06D0042D58D108E068460079207053E068468088F6\n"
+":4064800040BA20804EE00198694600BA000AC97900020843206045E0FFE720686C4622716171012D04D0022D04D0042D0DD105E0A0710AE0020AA271E07106E0020EA271E2\n"
+":4064C000020CE271020A227260720093AB1C01AA15480599FAF796FF040023D01248FAF7C1FE05460598009033462A4621461248FEF79EFA0C4E306801684908490001603D\n"
+":40650000012000F0F1FA306801680122114300E006E00160202D03D0032C01D005204DE707204BE7002049E7FC0D0020A01502089000002048160208F4150208F8B5114D80\n"
+":40654000114CA878002807D0122805D0112817D0082020710820F8BD0C4E0121306800F00FFB0127002805D009A0FEF761FA27710120F8BDAF70306800F0DCFA0020F8BDEE\n"
+":406580000320E6E790000020502C0020840000200A0A0A0D2053656D2057616974204661696C6564202121200A0D000070B5104C1049A078112808D00725102809D012285E\n"
+":4065C00007D0002805D04D750AE001204875082070BD094E0121306800F0D2FA002801D0072070BDA570306800F0A4FA002070BD90000020502C002084000020FEB5054658\n"
+":406600000F46002069461C460881002A0BD01F4901268B780321102B0AD01D48DA0604D486740120FEBD0220FEBD81740320FEBD012F05D0022F05D0042F05D01080F2E75C\n"
+":40664000118003E0042000E006201080002C1AD011882046F9F7FBFF280A2070657000963B4602AA294678200196FFF78FFE050004D008A0FEF7DCF92846FEBD68460089C7\n"
+":40668000010AA170E0700020FEBD000090000020502C0020204572726F722052656769737465722052656164204572726F72200A0D000000F8B504462148224E80781028BB\n"
+":4066C00007D0C00602D401207074F8BD03207074F8BD607821780002084345BA282D02D30A207074F8BDA01CF9F7BCFF00BA000A61790002144F08433860A07938710128CF\n"
+":4067000002D009207074F8BDE01DF9F7ABFF00BA000AA17A00020843B8600C480C4C85850121206800F02CFA002801D00720F8BD034805218170206800F0FCF90020F8BDFB\n"
+":4067400090000020502C0020642D00201419002084000020F8B504000AD0284E2848B17810290BD0C90605D4012141720846F8BD0220F8BD032141720846F8BD61782278D9\n"
+":40678000090211434DBA0A21062D02D341720A20F8BD1C4F0121386800F0F2F9002801D00720F8BDA01CF9F75DFF00BA010A60790902014314480160E179A279090211434B\n"
+":4067C00049BA4160617A227A0902114349BA8160E17AA27A0902114349BAC160617B227B0902114349BA0161084805850420B070386800F09FF90020F8BD00009000002039\n"
+":40680000502C002084000020502D00201419002070B50E4C0325A078102808D0C1060C4802D40121017209E00572032070BD094E0121306800F0A4F9002801D0012070BD44\n"
+":40684000A570306800F076F9002070BD90000020502C00208400002070B50F4CA078102809D0C1060D4802D40121C1710AE00321C171084670BD0A4D0121286800F080F9B3\n"
+":40688000002801D0012070BD0220A070286800F051F9002070BD000090000020502C00208400002070B50C4C0825A078112803D00A488575082070BD094E0121306800F0E8\n"
+":4068C0005FF9002801D0072070BDA570306800F031F9002070BD000090000020502C00208400002070B5224E0446B1782148102909D0C90603D40121C174084670BD0321D0\n"
+":40690000C174084670BD61782278090211431A4D49BA6980A1782972012907D0022907D0042914D00221C174084670BDE07804E02079E1780002084340BA104C686001212C\n"
+":40694000206800F01DF900280AD0072070BDE01CF9F788FE00BA000AA17900020843ECE70620B070206800F0E5F8002070BD000090000020502C002014190020840000209E\n"
+":4069800092B03F493D488860002080F3108862B6FAF7E8FEFDF7B8FCFDF764FAFDF766F9FDF7BAF9FDF7E2F9FDF72AFAFDF706FA3448C26A02210A43C262C06A324C08408B\n"
+":4069C000009008200D9001200E900320002510900F950DA92046FAF773FA002208212046FAF734FB2948C069009029480368C12228492948FEF71CF828A22BA12DA0FEF780\n"
+":406A000017F8F9F743FF1F4C40342069400002D50120FAF78FF920690121C90508432061FDF73CFA2B4C20222B486169F9F7F6FD0520A0810BA80B9500F063F8206201212C\n"
+":406A40000CA80C9500F062F8124960621422083101A8F9F7E3FD002101A800F0CDF80D49A06114221C3106A8F9F7D8FD002106A800F0C2F8E06100F03FF8FEE700040008D4\n"
+":406A800000ED00E000100240000400500020024000000140E0810008EC14020831343A30323A3438000000004665622032312032303230004275696C642044617465206123\n"
+":406AC0006E642054696D653A202573202573200A0D00000060000020BC18002001460020842900D0C81C704710B5002800D1012000F0EEFE002010BD10B500F057FF00206E\n"
+":406B000010BD10B5012000F0D5FF10BD10B5012901D0002010BD03220021012000F0DCFF040004D000231A46194601F0C9F8204610BD000038B5002405460094FFF736F97E\n"
+":406B400000280FD06946284601F046F9012801D0FF2038BD009800280DD0012007490007486008E000231A461946284601F0A8F8012800D0FF24204638BD000000ED00E0E9\n"
+":406B800038B5054600200090002D11D00024481C10D0002900D00C46FFF708F9002814D06A460021284601F051F9012815D104E0802038BD0024E443EEE7009800280ED069\n"
+":406BC000012008490007486009E0002322461946284600F0A3FF012801D0FF2038BD002038BD000000ED00E010B501F0BDF9012801D000F04DFF10BD3EB5044608200D468A\n"
+":406C0000205EFFF76BFF02A901910090208A2B4682B22168606801F07FF9012801D000203EBD02983EBD10B500F046FE002010BDFFB5044689B000276846878007821D4611\n"
+":406C400016460297002C11D00A98C4420ED02178432903D0F2A0FDF7EBFE07E0F84861780278914205D0F7A0FDF7E2FE02200DB0F0BD0A980B00C01E0390F948808807902E\n"
+":406C80000A982218F748203A0078FDF7E1FE180D2A67AAFDFCFBFAF9F8D8F7F7F7F7F7F6F5F4F3F2F1F0EFF7012802D0022804D085E201204003608029E0EB4902980A5CBE\n"
+":406CC000201882700298401C02902028F6D32021A01CFEF7EBFF029961188870CF7024203AE0012802D002281DD068E201A90020FFF79EFA002804D0DCA0FDF799FE6846E7\n"
+":406D00000782684680880102000A014361800221A01CFEF7CBFF2071677106203080D1490220087079E101A904A8FFF781FA0290002804D0CDA0FDF77BFE684607826846E3\n"
+":406D4000008A010AA170E0700221A01CFEF7AEFF2071029860710620308072E2012802D0022826D06DE20592D17F0398029181B2A01CFEF79BFF0299814207D005980A9904\n"
+":406D8000C27FC2A0C91EFDF753FE39E0E178A27808021043B24940BA8880002201A9FFF787FA40E0684681880802090A0843608081E0A21C01A90798FFF77AFA94E06946C7\n"
+":406DC0008988A01CFEF772FF69468988611888706946898802986118C87069468888001D71E0012802D0022823D02AE2D17F0398029181B2A01CFEF759FF0299814207D0E4\n"
+":406E0000ADA0FDF715FE6846878002200290C9E7E178A27808021043914940BA8880002201A9FFF73BF902900028BBD068468780B8E7A21C01A90798FFF730F954E0012827\n"
+":406E400002D002284BD0FCE1D17F0398029181B2A01CFEF72BFF0299814216D096A0FDF7E7FD68468780022002901EE0D7E1D3E1CFE1C4E1B5E166E156E18EE0E3E17AE078\n"
+":406E800076E072E06EE041E03AE0E178A27808021043734940BA8880002201A9FFF778F90290002801D068468780684680880102000A014361800221A01CFEF7F7FE20715E\n"
+":406EC000029860710620308066480178012912D002298AD068468088002886D06FE1A21C01A90798FFF754F90290002800D166E76846878063E76946898800297ED1A0E13B\n"
+":406F0000FFF71CFB57480770378056E154484088002810D070A0FDF78BFDFF20A070504841880A0AE270217103216A46918002210291478004E001A9A01CFEF7F5FF029099\n"
+":406F400069468988A01CFEF7B1FE69468988611888706946898802986118C87069468888001DF9E6FEF7B8FF6AE1FFF775FC67E1FFF74EFC64E1D17F0398029181B2A01C62\n"
+":406F8000FEF794FE0299814203D04BA0FDF750FD4FE1A01CFFF7DEFB52E1012802D002283DD00CE1D17F0398029181B2A01CFEF77DFE0299814207D03FA0FDF739FD684617\n"
+":406FC00087800220029012E0E178A27808021043234940BA8880002201A9FFF70DF80290002804D043A0FDF723FD68468780684680880102000A0143618000E00BE00221CF\n"
+":40700000A01CFEF753FE207102986071CDE06946898800297CD0022101702F80CFE078E020496E76616C6964205369676E617475726520307825303278202121200A0D000D\n"
+":4070400065000020204944203D2030782530327820213D20307825303278200A0D0000008800002066000020BC1800204572726F7220696E2047657474696E672053656EE3\n"
+":40708000736F72204944200A0D00000020435243204C656E677468203D203078253032782C206F72696720637263203D20307825303278200A0D00002043524320766572E5\n"
+":4070C000696669636174696F6E204572726F72202121200A0D0000004572726F7220696E204D435520697473656C66202121200A0D0000004572726F7220696E2047657490\n"
+":4071000074696E67204374726C200A0D0000000052E0A21C01A90798FEF76EFF0290002800D10DE7494857E0D17F0398029181B2A01CFEF7BBFD0299814200D025E7A01CBF\n"
+":40714000FFF7B8FA7CE0012802D0022839D036E0D17F0398029181B2A01CFEF7A7FD0299814202D039483C380FE0E178A27808021043374A40BAD08021791170002301AA29\n"
+":40718000FFF73CFA002804D032A0FDF751FC68468780684680880102000A014361800221A01CFEF783FD20716771062030802F480178012900D12AE7077005202880002004\n"
+":4071C00055E52348A31C017801AAC088FFF716FA02900028A5D01FA0FDF72AFC68468780AEE6D17F0398029181B2A01CFEF75EFD02998142A2D1A01CFFF774FB20E01CA0FD\n"
+":40720000FDF716FC204921A0FDF712FCF9F7D0FC16E0FFF7CBF913E0FFF744FB10E0D17F0398029181B2A01CFEF740FD0299814203D007491D48488002E0A01CFEF72AFE90\n"
+":4072400037800A48B8E7092011E50000F4700008880000204572726F7220696E205265616420495350200A0D00000000660000204657205570647420496E6974696174651C\n"
+":4072800064200A0D00000000B10B0008204669726D776172655F757064617465203D20307825303878200A0D000000000A200000F8B5134C0F46E66805462068001D00F016\n"
+":4072C00069FA681C07D1002F05D021680D48091D00F098FAF8BD2068751945602168B54204D2A06B091D00F075FAF8BD606B091D00F070FAA06A8542F7D2A562F8BD000099\n"
+":407300000C0000209C010020F8B5054600F086FA2A4CA068401CA0602068294F002803D06069002827D02CE02560A068012828D1002614207043C01900F03EFA761C072EAF\n"
+":40734000F7D31F488C3000F037FA1D48A03000F033FA1B48B43000F02FFA1948C83000F02BFA1748DC3000F027FA15488C3060631430A06305E02068E96AC06A884200D8B4\n"
+":407380002560606A401C60626864E86A2169884200D9206114214843C019291D00F032FA00F048FA6069002806D02068E96AC06A884201D200F080FAF8BD00000C000020B3\n"
+":4073C000C000002070B5114E114C18E000F014FB3068002817D000F09BFE00F01FFAF068C568281D00F0D6F9A068401EA0606068401E606000F01EFA284600F056F860684B\n"
+":407400000028E3D170BD00F083FEF8E7880100200C00002010B5026C0C46002A0CD0C1688B18C36041688B4201D2194601E00168C1602046F9F7F2F810BDF8B5856B17468A\n"
+":4074400004460026026C002A11D0002F19D0E068F9F7E4F8E168206C091AE1602268914202D26168081AE060022F17D019E02068002816D1606800F0E5FD064600206060F4\n"
+":407480000FE0A068F9F7CAF8216CA0684018A0606168884205D32068A06002E0002D00D06D1E6D1CA5633046F8BD10B50446006B00F0CEF9204600F0CBF910BD03210E488B\n"
+":4074C0008902420705D0C01DC0080B4AC000821A891A0A4A0023411809C20839C908C900183A11604B600B600B1A0AC093600120C0075360D0607047B001002058000020EE\n"
+":40750000044CFFF75FFF20680128FAD900F0D4F9F7E70000C0000020FFB581B097000C9C0E460A9DA5223946206BF9F789F8206B3F1FC019C708FF00780701D072B6FEE75A\n"
+":407540002218315C20321175315C002902D0401C1028F5D32046403000260090C670072D00D30625E5622665201DE56400F02FF92046183000F02BF924610720401B646295\n"
+":40758000A0616665009806763846049A019900F0F1F820600B98002800D0046005B0F0BD30B5114900E011460A688242FBD34B685C18844203D140681818486008464368C7\n"
+":4075C0001C18944209D1084C103C2468A24209D052689A1842600A6812680260814200D0086030BD0460F9E75800002010B5044600F014F9A06B002804D0002400F01AF984\n"
+":40760000204610BD0124F9E70648416B0968002905D0416BC968C9684968816270470021C943FAE70C00002003480068401C72B600D0FEE7FEE7000008000020F8B5044626\n"
+":4076400000F0ECF8254640350526AE57274624370BE0606A00280AD0384600F027FD002801D000F04DF9761E76B2002EF1DC0027FF436F7100F0DEF800F0D0F80426AE5739\n"
+":407680002046103000900BE0206900280AD0009800F00CFD002801D000F032F9761E76B2002EF1DC2F7100F0C5F8F8BDF8B50546002700F0A1F9284E3068002801D1FFF719\n"
+":4076C000FDFEF06805423FD1002D3DD00835680708D06807400F0821081A4519680701D072B6FEE7002D2FD0706885422CD81A48103001460C6801E020460C466168A942F5\n"
+":4077000002D221680029F7D131688C421CD007682168016060680837411B102908D96019420701D072B6FEE741606560FFF738FF61687068401A7060B268904200D2B06006\n"
+":40774000F0680143002003C400F0E2FC780701D072B6FEE73846F8BD4800002004490868002803D00868026D521C0265086870470C00002010B50124031F24061C601B1F15\n"
+":407780001960191F024B0B60143940380A6010BD297600084368826801699A60836842685A604A68824201D182684A60002202610868401E086070470146083100224160E4\n"
+":4077C000D243C1608260016100210160704700210161704730B50B685A1C02D00246083202E0026904E02246546825689D42FAD953684B6099608A60516008610168491CB5\n"
+":40780000016030BD42684A6093688B6093685960916008610168491C0160704772B604480168491C0160BFF34F8FBFF36F8F70470800002005490868002804D0401E08608A\n"
+":4078400000D162B6704772B6FEE700000800002070B500281AD004460D4D083C6068E968084201D172B6FEE72268002A01D072B6FEE78843606000F0BFF86068696840181D\n"
+":4078800068602046FFF78CFE00F042FC70BD00004800002010B506487D21C9000068F8F763FE0449401E48610720086110BD00000000002000E000E0012004490007486077\n"
+":4078C000BFF34F8FBFF36F8F7047000000ED00E010B502000FD00948006B002801D072B6FEE700F089F800211046FFF7E1FC00F00FFC002801D1FFF7DFFF10BD0C000020DF\n"
+":4079000001490120C86170470C00002010B50C46002809D0054909681831FFF75BFF01212046FFF7C5FC10BD72B6FEE70C00002070B5040025D0154DE06A2968C96A8842C3\n"
+":407940001FD2A069002804DB28680721C06A081AA061E06A14220E4E504361698019814210D1201DFFF716FF2868C06AE0622969884200D92861142148438019211DFFF7FC\n"
+":4079800041FF70BD2868C06AE06270BD0C000020C0000020002805D003490A6A0260C9684160704772B6FEE70C0000201CB50E4800240190234680220CA100940D4800F0D7\n"
+":4079C000ABFA012803D0401C0CD172B6FEE772B600210548C9432C38816201214161C46000F03EF81CBD00003800002049444C4500000000017500080248016B491C01635D\n"
+":407A0000704700000C00002010B51348016B002902D00121C16110BD0021C16101690F4A02E0002915D0491E14234B43D358002BF7D014234B439A18536814465B68083401\n"
+":407A40005360A34201D15B685360DA680260016110BD72B6FEE700000C000020C000002010B50948016AFF22120411430162016A120211430162FFF70DFF044900200860BE\n"
+":407A8000F8F728FD002010BD00ED00E00800002010B5F8F733FD044600F076FA002803D001200349000748602046F8F72BFD10BD00ED00E010B502460021012000F00CF8D1\n"
+":407AC000041E07D00021416001600B460A46C16000F0F6F8204610BDF8B517460E46050016D0002E16D070435030FFF7DFFD04000CD020465030002E0ED0206026642046F3\n"
+":407B00000121E56300F0A6F84C2007552046F8BD72B6FEE70020E7E72460EFE7FFB5002583B0040003D00498002802D006E072B6FEE7206C002801D072B6FEE700F014FA19\n"
+":407B40000026002804D10598002801D072B6FEE7FFF764FEA76B002F26D0E56820460499FFF758FC0698002810D0E560606A002807D02046243000F099FA002801D0FFF736\n"
+":407B80009BFEFFF757FE012007B0F0BD7F1EA7632068002802D1FFF7E1FD606020690028EFD020461030E6E70598002802D0002D03D006E0FFF73EFE27E06846FFF7EAFE79\n"
+":407BC0000125FFF737FEFFF717FFFFF727FE2046403004214156491C00D1067105214156491C00D14671FFF725FE05A9684600F069F9002820460AD0FFF720FD00F088FA70\n"
+":407C00002046FFF7F3FC0028A2D00020BCE7FFF7EDFC002818D02068002806D1FFF7FEFD6068FFF785FEFFF705FE204624300599FFF76CFE2046FFF701FD00F069FA00286E\n"
+":407C400086D1FFF739FE83E72046FFF7F7FC00F05FFA7DE770B50D46040025D0FFF7DEFD216CE06B48432168411861600021A1632168A160E06B216C401E48432168411880\n"
+":407C8000E1600021C94320464030017141713038002D0BD0FFF790FD20462430FFF78CFDFFF7C8FD012070BD72B6FEE721690029F6D000F0FBF90028F2D0FFF7FDFDEFE70D\n"
+":407CC000FFB5002683B01D46040003D00498002802D006E072B6FEE7206C002801D072B6FEE7022D04D1E06B012801D072B6FEE700F03AF90027002804D10598002801D0EF\n"
+":407D000072B6FEE7FFF78AFDA06BE16B884207D3022D05D00598002817D0002E18D01BE02A4620460499FFF788FB616A002903D02046243000F0BAF9002801D0FFF7BCFD45\n"
+":407D4000FFF778FD012007B0F0BDFFF773FD22E06846FFF71FFE0126FFF76CFDFFF74CFEFFF75CFD2046403004214156491C00D1077105214156491C00D14771FFF75AFD9D\n"
+":407D800005A9684600F09EF8002806D02046FFF755FC00F0BDF90020D5E7FFF73FFDA06BE16B884210D1FFF745FD204610300599FFF7ACFD2046FFF741FC00F0A9F9002812\n"
+":407DC000A0D1FFF779FD9DE7FFF734FD2046FFF735FC00F09DF995E770B50D46040004D0206C002803D072B6FEE772B6FEE72068002804D16068002801D072B6FEE7F8F739\n"
+":407E00007DFBA26B0646E06B904219D92146403105200856521CA263421C03D0401C487101240EE0606A0028FAD02046243000F03DF90028F4D0002DF2D001202860EFE745\n"
+":407E400000243046F8F75EFB204670BDF7B582B0040003D00398002802D006E072B6FEE7206C002801D072B6FEE7F8F747FB0090A66B002E1FD020464030042545570746E7\n"
+":407E800020460399FFF7C6FA761EA663681C03D06D1C3D7101240FE020690028FAD02046103000F003F90028F4D004980028F1D001210160EEE700240098F8F723FB2046C6\n"
+":407EC00005B0F0BD70B50D4604001AD0002D1AD0FFF7A4FC0F4AD1682868431C0FD02368126A934202D062688A420ED96268891A81420AD2401A28602046FFF74BFD0024CC\n"
+":407F000004E072B6FEE772B6FEE70124FFF792FC204670BD0C000020FFB585B0164690000F9FFFF7C3FB05001AD05C20FFF7BEFB040012D0256300210E9803910197009099\n"
+":407F400002943246089B06990598FFF7E5FA2046FFF7DAF9012009B0F0BD2846FFF778FC0020C043F7E7000006484169002904D0006B002803D00020704701207047022084\n"
+":407F8000704700000C000020F8B52C4C0027206B002808D0A069401CA061E069002800D001273846F8BDE668761CE6600ED1606B0068002801D072B6FEE7606BA16B61632C\n"
+":407FC000A063206A401C2062FFF71EFBA06A86420AD3606B0068002810D0606BC068C568686886420DD2A06220681421C06A4843134908580128D0D90127CEE70020C04384\n"
+":40800000F1E7281DFFF7C6FBA86A002803D028461830FFF7BFFBE86A2169884200D920611421484306494018291DFFF7EBFBE86A2168C96A8842CCD30127CAE70C000020F4\n"
+":40804000C000002070B500210446002828D0154D2868844201D072B6FEE7206D002808D0401E2065E36CE26A9A4219D0002802D016E072B6FEE7201DFFF78CFBE06C0721DF\n"
+":40808000E062081AA061E06A2969884200D928611421484304494018211DFFF7B3FB0121084670BD0C000020C000002070B5C068C468002C0BD0204618300646FFF76AFB8E\n"
+":4080C000114D286B002804D0314610480FE072B6FEE7201DFFF75EFBE06A2969884200D92861142148430949B4394018211DFFF789FBE06A2968C96A884202D90120E86108\n"
+":4081000070BD002070BD00000C00002074010020F8B5284C0025206B2E46002808D0FFF77DFB206B401E2063206B002802D03DE072B6FEE7A168204F00291DD136E0F86831\n"
+":40814000C56828461830FFF725FB281DFFF722FBE86A2169884200D92061142148431649B4394018291DFFF74DFBE86A2168C96A884201D30120E06138680028DFD1002D13\n"
+":4081800001D0FFF741FAA569002D09D00127FFF7FBFE002800D0E7616D1EF8D10020A061E069002802D00126FFF786FBFFF742FB3046F8BD0C0000207401002000000000DD\n"
+":4081C000000000000102030406070809030406080C1018203000000000010203040000006D61696E0000000040150208914100080000000000000000000100003415020882\n"
+":408200002D340008000000000000000080000000537461727444656661756C745461736B0048414C5F4932435F536C617665547843706C7443616C6C6261636B0048414C62\n"
+":408240005F4932435F536C617665527843706C7443616C6C6261636B0048414C5F4932435F4572726F7243616C6C6261636B0048414C5F4932435F4164647243616C6C620B\n"
+":4082800061636B0048414C5F4932435F4C697374656E43706C7443616C6C6261636B0048414C5F4932435F4D656D547843706C7443616C6C6261636B0048414C5F49324361\n"
+":4082C0005F4D656D527843706C7443616C6C6261636B0048414C5F4932435F41626F727443706C7443616C6C6261636B0048414C5F4750494F5F455854495F43616C6C6274\n"
+":4083000061636B004669726D776172655F557064617465004F7074696F6E4279746550726F6700424642325F636865636B5F656E61626C6500000000555956598002E0018B\n"
+":4083400001004B00010000000000000000000000555956590005D00201006400010000000000000000000000555956590005C00301004B00010000000000000000000000A4\n"
+":4083800055595659800738040100410001000000000000000000000055595659000AA0050100260001000000000000000000000055595659200A980701001C0001000000E2\n"
+":4083C0000000000000000000555956598002E00101004B00010000000000000000000000555956590005D00201006400010000000000000000000000555956590005C003B1\n"
+":4084000001004B0001000000000000000000000055595659800738040100410001000000000000000000000055595659000AA0050100260001000000000000000000000058\n"
+":4084400055595659200A980701001C000100000000000000000000000009980001000000F1FFFFFF0F00000000000000010000000000000000000000000000000000000018\n"
+":4084800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC\n"
+":4084C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004272696768746E65737300000000000063\n"
+":40850000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A\n"
+":4085400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FB\n"
+":4085800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BB\n"
+":4085C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007B\n"
+":40860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A\n"
+":4086400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA\n"
+":4086800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA\n"
+":4086C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A\n"
+":408700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039\n"
+":4087400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F9\n"
+":408780000000000000000000000000000000000000000000000000000109980001000000000000001E0000000A0000000100000000000000000000000000000000000000ED\n"
+":4087C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079\n"
+":40880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436F6E74726173740000000000000000EA\n"
+":4088400000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D7\n"
+":4088800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B8\n"
+":4088C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078\n"
+":408900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\n"
+":4089400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7\n"
+":4089800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B7\n"
+":4089C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077\n"
+":408A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036\n"
+":408A400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6\n"
+":408A800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6\n"
+":408AC0000000000000000000000000000000000000000000000000000209980001000000000000003C00000010000000010000000000000000000000000000000000000085\n"
+":408B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035\n"
+":408B400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053617475726174696F6E000000000000CB\n"
+":408B80000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094\n"
+":408BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075\n"
+":408C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034\n"
+":408C400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F4\n"
+":408C800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4\n"
+":408CC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074\n"
+":408D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033\n"
+":408D400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3\n"
+":408D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B3\n"
+":408DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073\n"
+":408E00000000000000000000000000000000000000000000000000000C09980001000000000000000100000001000000010000000000000000000000000000000000000081\n"
+":408E400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F2\n"
+":408E800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057686974652042616C616E636520417515\n"
+":408EC000746F00000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D\n"
+":408F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031\n"
+":408F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1\n"
+":408F800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1\n"
+":408FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071\n"
+":409000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030\n"
+":4090400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0\n"
+":4090800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0\n"
+":4090C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070\n"
+":40910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F\n"
+":40914000000000000000000000000000000000000000000000000000100998000100000028000000F4010000DC000000010000000000000000000000000000000000000043\n"
+":4091800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AF\n"
+":4091C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047616D6D6100000000000000000000008C\n"
+":40920000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D\n"
+":4092400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EE\n"
+":4092800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AE\n"
+":4092C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006E\n"
+":40930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D\n"
+":4093400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ED\n"
+":4093800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AD\n"
+":4093C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006D\n"
+":40940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C\n"
+":4094400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC\n"
+":409480000000000000000000000000000000000000000000000000001A09980001000000E80300001027000094110000010000000000000000000000000000000000000028\n"
+":4094C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C\n"
+":4095000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057686974652042616C616E63652054658B\n"
+":409540006D706572617475726500000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5\n"
+":4095800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB\n"
+":4095C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B\n"
+":40960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A\n"
+":4096400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA\n"
+":4096800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA\n"
+":4096C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A\n"
+":409700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029\n"
+":4097400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9\n"
+":4097800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9\n"
+":4097C0000000000000000000000000000000000000000000000000001B09980001000000000000007F0000001000000001000000000000000000000000000000000000001C\n"
+":409800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028\n"
+":4098400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053686172706E6573730000000000000031\n"
+":409880000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087\n"
+":4098C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068\n"
+":409900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027\n"
+":4099400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7\n"
+":4099800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7\n"
+":4099C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067\n"
+":409A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026\n"
+":409A400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6\n"
+":409A800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6\n"
+":409AC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066\n"
+":409B00000000000000000000000000000000000000000000000000001309980001000000010000006400000001000000010000000000000000000000000000000000000009\n"
+":409B400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5\n"
+":409B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004761696E00000000000000000000000026\n"
+":409BC0000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044\n"
+":409C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\n"
+":409C400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4\n"
+":409C800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4\n"
+":409CC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064\n"
+":409D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023\n"
+":409D400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3\n"
+":409D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3\n"
+":409DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063\n"
+":409E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022\n"
+":409E400000000000000000000000000000000000000000000000000001099A000100000000000000020000000000000000000000000000000000000000000000000000003B\n"
+":409E800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2\n"
+":409EC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004578706F73757265204175746F0000004E\n"
+":409F00000000000000000000000000000000000003000346756C6C20464F56204175746F204D6F646500000000000000000000000000004D616E75616C204D6F646500001C\n"
+":409F400000000000000000000000000000000000000000524F49204261736564204175746F204D6F646500000000000000000000000000000000000000000000000000009A\n"
+":409F800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1\n"
+":409FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061\n"
+":40A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\n"
+":40A0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0\n"
+":40A0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0\n"
+":40A0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060\n"
+":40A10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F\n"
+":40A1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF\n"
+":40A1800000000000000000000000000000000000000000000000000002099A000100000001000000CC100000380100000100000000000000000000000000000000000000E2\n"
+":40A1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005F\n"
+":40A200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004578706F73757265204162736F6C7574C9\n"
+":40A240006500000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058\n"
+":40A28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E\n"
+":40A2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005E\n"
+":40A30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D\n"
+":40A3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DD\n"
+":40A38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D\n"
+":40A3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005D\n"
+":40A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C\n"
+":40A4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DC\n"
+":40A48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009C\n"
+":40A4C0000000000000000000000000000000000000000000000000000D099A000100000064000000200300006A0000000100000000000000000000000000000000000000B9\n"
+":40A50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B\n"
+":40A540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A6F6F6D00000000000000000000000036\n"
+":40A58000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A\n"
+":40A5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005B\n"
+":40A60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A\n"
+":40A6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA\n"
+":40A68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A\n"
+":40A6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A\n"
+":40A700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019\n"
+":40A7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D9\n"
+":40A780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099\n"
+":40A7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059\n"
+":40A8000000000000000000000000000000000000000000000000000008099A0001000000C01CF6FF40E309000000000001000000000000000000000000000000000000006E\n"
+":40A8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D8\n"
+":40A8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050616E0000000000000000000000000079\n"
+":40A8C0000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\n"
+":40A900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017\n"
+":40A9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D7\n"
+":40A980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097\n"
+":40A9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057\n"
+":40AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016\n"
+":40AA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D6\n"
+":40AA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096\n"
+":40AAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056\n"
+":40AB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015\n"
+":40AB400000000000000000000000000000000000000000000000000009099A0001000000C01CF6FF40E309000000000001000000000000000000000000000000000000002A\n"
+":40AB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095\n"
+":40ABC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054696C74000000000000000000000000B8\n"
+":40AC000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3\n"
+":40AC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4\n"
+":40AC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094\n"
+":40ACC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054\n"
+":40AD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013\n"
+":40AD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D3\n"
+":40AD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093\n"
+":40ADC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053\n"
+":40AE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012\n"
+":40AE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D2\n"
+":40AE80000000000000000000000000000000000000000000000000002D099A0001000000000000000F000000080000000100000000000000000000000000000000000000A9\n"
+":40AEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052\n"
+":40AF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044656E6F6973650000000000000000004A\n"
+":40AF400000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0\n"
+":40AF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091\n"
+":40AFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051\n"
+":40B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\n"
+":40B0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D0\n"
+":40B080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090\n"
+":40B0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050\n"
+":40B10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F\n"
+":40B1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CF\n"
+":40B18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008F\n"
+":40B1C0000000000000000000000000000000000000000000000000001409980001000000000000000100000000000000010000000000000000000000000000000000000097\n"
+":40B20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E\n"
+":40B24000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000486F72697A6F6E74616C20466C697000F9\n"
+":40B28000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008C\n"
+":40B2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E\n"
+":40B30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D\n"
+":40B3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CD\n"
+":40B38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D\n"
+":40B3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004D\n"
+":40B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C\n"
+":40B4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC\n"
+":40B48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008C\n"
+":40B4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C\n"
+":40B500000000000000000000000000000000000000000000000000001509980001000000000000000100000000000000010000000000000000000000000000000000000052\n"
+":40B5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB\n"
+":40B58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566572746963616C20466C6970000000A6\n"
+":40B5C0000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049\n"
+":40B60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A\n"
+":40B6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA\n"
+":40B68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A\n"
+":40B6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004A\n"
+":40B700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009\n"
+":40B7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C9\n"
+":40B780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089\n"
+":40B7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049\n"
+":40B800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008\n"
+":40B8400000000000000000000000000000000000000000000000000026099A000100000000000000FFFF0000808000000100000000000000000000000000000000000000FF\n"
+":40B880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088\n"
+":40B8C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000524F49204578706F7375726500000000E3\n"
+":40B9000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6\n"
+":40B9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C7\n"
+":40B980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087\n"
+":40B9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047\n"
+":40BA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006\n"
+":40BA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C6\n"
+":40BA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086\n"
+":40BAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046\n"
+":40BB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005\n"
+":40BB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C5\n"
+":40BB800000000000000000000000000000000000000000000000000024099A0001000000080000004000000018000000080000000000000000000000000000000000000055\n"
+":40BBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045\n"
+":40BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000524F492057696E646F772053697A6500C7\n"
+":40BC400000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3\n"
+":40BC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084\n"
+":40BCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044\n"
+":40BD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\n"
+":40BD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3\n"
+":40BD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083\n"
+":40BDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043\n"
+":40BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n"
+":40BE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C2\n"
+":40BE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082\n"
+":40BEC00000000000000000000000000000000000000000000000000031099A0001000000401F0000B08F0600E02202000100000000000000000000000000000000000000C4\n"
+":40BF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n"
+":40BF40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004578706F7375726520436F6D70656E7371\n"
+":40BF80006174696F6E000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045\n"
+":40BFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041\n"
+":40C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
+":40C0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0\n"
+":40C080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080\n"
+":40C0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040\n"
+":40C1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF\n"
+":40C1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BF\n"
+":40C18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007F\n"
+":40C1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003F\n"
+":40C200000000000000000000000000000000000000000000000000002A099A000100000000000000020000000000000000000000000000000000000000000000000000002E\n"
+":40C2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BE\n"
+":40C280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004672616D652053796E63000000000000D6\n"
+":40C2C0000000000000000000000000000000000003000344697361626C65204672616D652053796E6300000000000000000000000000004672616D652053796E6320333091\n"
+":40C3000020487A000000000000000000000000000000004672616D652053796E6320363020487A00000000000000000000000000000000000000000000000000000000000B\n"
+":40C3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BD\n"
+":40C38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007D\n"
+":40C3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003D\n"
+":40C4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC\n"
+":40C4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC\n"
+":40C48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007C\n"
+":40C4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003C\n"
+":40C5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FB\n"
+":40C5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BB\n"
+":40C58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007B\n"
+":40C5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003B\n"
+":40C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA\n"
+":40C6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA\n"
+":40C68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A\n"
+":40C6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A\n"
+":40C7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F9\n"
+":40C7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9\n"
+":40C780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079\n"
+":40C7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039\n"
+":40C8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F8\n"
+":40C8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B8\n"
+":40C880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078\n"
+":40C8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038\n"
+":40C9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7\n"
+":40C9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B7\n"
+":40C980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077\n"
+":40C9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\n"
+":40CA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6\n"
+":40CA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6\n"
+":40CA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076\n"
+":40CAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036\n"
+":40CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5\n"
+":40CB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B5\n"
+":40CB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075\n"
+":40CBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035\n"
+":40CC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F4\n"
+":40CC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4\n"
+":40CC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074\n"
+":40CCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034\n"
+":40CD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3\n"
+":40CD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B3\n"
+":40CD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073\n"
+":40CDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033\n"
+":40CE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F2\n"
+":40CE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B2\n"
+":40CE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072\n"
+":40CEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032\n"
+":40CF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1\n"
+":40CF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1\n"
+":40CF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071\n"
+":40CFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031\n"
+":40D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0\n"
+":40D0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0\n"
+":40D080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070\n"
+":40D0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030\n"
+":40D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EF\n"
+":40D1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AF\n"
+":40D18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F\n"
+":40D1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F\n"
+":40D2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EE\n"
+":40D2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AE\n"
+":40D28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006E\n"
+":40D2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E\n"
+":40D3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ED\n"
+":40D3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AD\n"
+":40D38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006D\n"
+":40D3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D\n"
+":40D4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC\n"
+":40D4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AC\n"
+":40D48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C\n"
+":40D4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C\n"
+":40D5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB\n"
+":40D5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB\n"
+":40D58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B\n"
+":40D5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B\n"
+":40D6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA\n"
+":40D6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA\n"
+":40D68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A\n"
+":40D6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A\n"
+":40D7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9\n"
+":40D7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9\n"
+":40D780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069\n"
+":40D7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029\n"
+":40D8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8\n"
+":40D8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8\n"
+":40D880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068\n"
+":40D8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028\n"
+":40D9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7\n"
+":40D9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7\n"
+":40D980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067\n"
+":40D9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027\n"
+":40DA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6\n"
+":40DA400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6\n"
+":40DA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066\n"
+":40DAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026\n"
+":40DB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5\n"
+":40DB400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5\n"
+":40DB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065\n"
+":40DBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025\n"
+":40DC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4\n"
+":40DC400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4\n"
+":40DC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064\n"
+":40DCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\n"
+":40DD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3\n"
+":40DD400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3\n"
+":40DD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063\n"
+":40DDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023\n"
+":40DE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2\n"
+":40DE400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2\n"
+":40DE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062\n"
+":40DEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022\n"
+":40DF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1\n"
+":40DF400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1\n"
+":40DF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061\n"
+":40DFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021\n"
+":40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0\n"
+":40E0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0\n"
+":40E080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060\n"
+":40E0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\n"
+":40E1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF\n"
+":40E14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009F\n"
+":40E18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005F\n"
+":40E1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F\n"
+":40E2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DE\n"
+":40E24000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E\n"
+":40E28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005E\n"
+":40E2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E\n"
+":40E3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DD\n"
+":40E34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D\n"
+":40E38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005D\n"
+":40E3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D\n"
+":40E4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DC\n"
+":40E44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009C\n"
+":40E48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005C\n"
+":40E4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C\n"
+":40E5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DB\n"
+":40E54000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009B\n"
+":40E58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005B\n"
+":40E5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B\n"
+":40E6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA\n"
+":40E64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A\n"
+":40E68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005A\n"
+":40E6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A\n"
+":40E7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D9\n"
+":40E740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099\n"
+":40E780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059\n"
+":40E7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019\n"
+":40E8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D8\n"
+":40E840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098\n"
+":40E880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058\n"
+":40E8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018\n"
+":40E9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D7\n"
+":40E940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097\n"
+":40E980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057\n"
+":40E9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017\n"
+":40EA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D6\n"
+":40EA40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096\n"
+":40EA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056\n"
+":40EAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016\n"
+":40EB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D5\n"
+":40EB40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095\n"
+":40EB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055\n"
+":40EBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015\n"
+":40EC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4\n"
+":40EC40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094\n"
+":40EC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054\n"
+":40ECC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014\n"
+":40ED000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D3\n"
+":40ED40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093\n"
+":40ED80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053\n"
+":40EDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013\n"
+":40EE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D2\n"
+":40EE40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092\n"
+":40EE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052\n"
+":40EEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012\n"
+":40EF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D1\n"
+":40EF40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091\n"
+":40EF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051\n"
+":40EFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011\n"
+":40F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D0\n"
+":40F040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090\n"
+":40F080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050\n"
+":40F0C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\n"
+":40F1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CF\n"
+":40F14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008F\n"
+":40F18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004F\n"
+":40F1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F\n"
+":40F2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CE\n"
+":40F24000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008E\n"
+":40F28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E\n"
+":40F2C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E\n"
+":40F3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CD\n"
+":40F34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D\n"
+":40F38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004D\n"
+":40F3C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D\n"
+":40F4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC\n"
+":40F44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008C\n"
+":40F48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C\n"
+":40F4C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C\n"
+":40F5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB\n"
+":40F54000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008B\n"
+":40F58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004B\n"
+":40F5C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B\n"
+":40F6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA\n"
+":40F64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A\n"
+":40F68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004A\n"
+":40F6C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A\n"
+":40F7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C9\n"
+":40F740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089\n"
+":40F780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049\n"
+":40F7C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009\n"
+":40F8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C8\n"
+":40F840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088\n"
+":40F880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048\n"
+":40F8C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008\n"
+":40F9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C7\n"
+":40F940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087\n"
+":40F980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047\n"
+":40F9C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007\n"
+":40FA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C6\n"
+":40FA40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086\n"
+":40FA80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046\n"
+":40FAC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006\n"
+":40FB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C5\n"
+":40FB40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085\n"
+":40FB80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045\n"
+":40FBC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005\n"
+":40FC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C4\n"
+":40FC40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084\n"
+":40FC80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044\n"
+":40FCC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004\n"
+":40FD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3\n"
+":40FD40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083\n"
+":40FD80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043\n"
+":40FDC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\n"
+":40FE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C2\n"
+":40FE40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082\n"
+":40FE80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042\n"
+":40FEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n"
+":40FF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C1\n"
+":40FF40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081\n"
+":40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041\n"
+":40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n"
+":020000040801F1\n"
+":4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0\n"
+":400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080\n"
+":400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040\n"
+":4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
+":4001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BF\n"
+":40014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007F\n"
+":40018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003F\n"
+":4001C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF\n"
+":4002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BE\n"
+":40024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007E\n"
+":40028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E\n"
+":4002C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FE\n"
+":4003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BD\n"
+":40034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007D\n"
+":40038000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003D\n"
+":4003C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FD\n"
+":4004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC\n"
+":40044000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007C\n"
+":40048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003C\n"
+":4004C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC\n"
+":4005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BB\n"
+":40054000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007B\n"
+":40058000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003B\n"
+":4005C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FB\n"
+":4006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA\n"
+":40064000000000000000000000000000000000000000000000000000050003EC00000000000003E054A20B3371E40C0071DC00005002029C501C0F00502B00020040000693\n"
+":40068000503E00015018FD9A501F0006000000010100000200800000502E0100504500021000003350410002FD00030050340800500A02005030208054403C0E505A0E3EEB\n"
+":4006C000507500030CCC0CCC080071CC14085088001150930004000CFFBEFAE1399950A6399950A03FEF507E0199507B00020CCC100050FE00C850F4033350F100020CCC2D\n"
+":400700001CCC50FA014750F700020B33133350EE033350DC012C50C8033350C500020CCC1CCC50D0033350CD000213331CCC50D800A350D5000206660CCC50A8000250BAA3\n"
+":40074000FFFF50AA400450B8020C50BD0002640C001852CA003F53160147531CFFD8531A0CCC52D60FAE5322200053410002D80004007078000453240C0053280400714B63\n"
+":40078000000204000400551000CC52B700025DE77EEF52BF000401990199019901995539000310001000100053B4000053E5000200CC00CC54B20147551404005512008089\n"
+":4007C000544E0019544C00035049000500000000023200CC2000548900088000F8008000FE6709997E6680007E6654A81000300E00BB200900024000400030090002400086\n"
+":400800004000400900024000400010128000118D00020080008011670004000000004000400011910003010000800080F039000200003390E00100020001000011860388D5\n"
+":4008400061140006118900020000000060F1000280008000610B0005000009C407D0012C00146116001960FC0FD76126000860E000A660E500020186A00060E20CCC613256\n"
+":400880009600601D00020000653860164000201001705398350F202E000140100000100900020001FFDD602900020000199A20300014302E0014403000145344004F52AAEF\n"
+":4008C0000000202C03F1302C03F1402C03F111750002FFFFB50211810002FFFFB54060180001600C0211604A036C503240002014000120120001200100020A2807A02022CB\n"
+":40090000041920203C0020250004000041000000821430140000300100020A2807A030201E0030250004000082140001045030220419300E00004014000140010002078030\n"
+":40094000043840203C0040250004000041000000410040220419401200507078000460B10008A974B3A0B4A0B4ACB4ECB4F80000A88460004F38201001606016400071C291\n"
+":40098000056671C003006025000200300000602D00020034030060390002001902006031000200000000603D000200000000603440006040400020510008000100080001FC\n"
+":4009C000000900030002000100062065000A000300000001000900000006000100260001002630550008000100080001000900030002000100063069000A0003000000019F\n"
+":400A0000000900000006000100260001002640510008000100080001000900030002000100064065000A000300000001000900000006000100260001002660290002000105\n"
+":400A40000000000006000008000100010300AA940000000000006538380000E83C3038CB4086A201AE129A0129AC130EE086F84C89CE069980F26469ABD03B820288C68058\n"
+":400A8000423E9C5E66103080D20877A5411040C1681E083D6AD65E9C291EF4D5105041404A88115BB47244C938059F46B5887C0F04081520686C0F7028913441634016EC96\n"
+":400AC00093D90839886882A6882C6902DE8B619EC0099F4329082C69C300C06C1FFD024220A9A0C10430301072757105671105403BFD0060EF2163F486D18CA1C56A06F486\n"
+":400B0000CF20094E7C4200163275F6020076E91C226F7F6221E9D08319BD24B87200F32F217A6D80866C2132177A481886047A30DA65802631E6D681A6406AF80FCA466060\n"
+":400B400078D001FA276C7C1FF826C002059CD4440DA2EC856002276790294C09214101DE7E23E40C999400351406D160121041E00468870060141AF1CA8135437E7B3A2003\n"
+":400B800068DC09849DAA2A44190070EFD7E210016774680E4748CA7EFA34FC895251013435E9DD510F3AB4B9036A604C2A02CCA5009D8066A1038E648B1EBD471EEB4D19CD\n"
+":400BC000816F586121BEBE883FBF3608206883DE14492DFE60413F48CD08C40F8408C208B499FE748143D03DD13262009DA1AEFB3080E41AA1BD5E882246F536C1187CCED0\n"
+":400C00006C8F4044D00509002CFF30FAB8EC41328020E9BDA2DFEAC411E4B2C2089A5EA06F1E897120308209020EB15412865A14E00011534AE86030040223E155220E4615\n"
+":400C40000A86400D3ED1036A2040E12BD27B88D530E2C232D309B11A04D1A24DF074E126E0D12712271913AA275913DBDB8093C69313F0B1E37731E46B830A24FA00041040\n"
+":400C8000802962A6862250348A083128148A15142C8A25144C8A35146C8A45148C8A5514AC8A6514CC8A7514EC8A85150C8A95152C7B34FC6140AA48AA834793149B8FA29A\n"
+":400CC0001C04ABF50348C1001090129348AC8B1620D0F43148C100169018A03526915B162C41A2572457322BD457B22C1458322C5458B22C9459322CD459B22D145A322DB6\n"
+":400D0000545AB22D945B322DD45BB22E145C322E545CB22E945D322ED45D9420741081E90206822250348BC8312F144A1046144BD48BD8343D3D34304009A40A2815502C56\n"
+":400D40009348BE8D1620D12FD22FD89420BC2898091810689829182C8C25184C8C35186C8C457906846085869866250348C500F59D186DA4823B8D8D7003E11DF94E316BBE\n"
+":400D800039E478C94C901384F508F04A23C1408878E062C5A48A11E6304792C2CA83666163287047AB86847B2611F429B10F99190240615E1206084881E11F33F91119285C\n"
+":400DC000101B18909181033DE87C4467593D15D80246850CFA5120892F4A2814C82491E8D5C602499488F7CCC168FE07CD044649B37A84B0C129E8A0A2B490929E9AEC296A\n"
+":400E000010928562203707252C69F5C1540496A04534092DD99AC5460499E72002035AD849EC308203522128850479B9951447633E170E22940C47D1004453D38129F87F6A\n"
+":400E4000415DDC25471B882E0178254080CF9A1908A81411F42D611515202544904A8A283C15AA6080FC47BD2788A92519F42DF11532012A67A12AA900E18E18202E11B7D8\n"
+":400E8000251552E101684095540840568AB0311F343A11560C23E493222B44847D29A0456F128428A1C8C1AE71CC30817A50F5226115FC90E8A9C095FC4A20B5AC325902E0\n"
+":400EC0000CFA17308B30711F458711667A23E881622DB9544150612D87C47CD14045B9E0CF4AA511701233E85FA22E4B44A9309744835D83A025D880D4F425F838D7084CFA\n"
+":400F000012FC2C6AAB84BFE48EC4D17FE079644D12611F139011A7CB2F0A9009A7C4B20A8009A67423E8CE423569309AD4404D6A80135AA104269F84D6482651AF59C213A0\n"
+":400F400051C13629109B5AD7F909AC2826D7535514F026FE52B89C32E1396C14272D5509DA6822784B087444FA8A163A15604FBEA0C82A3027E44152E13F3A3050BD113CDC\n"
+":400F800054404FF9884266B29ECBAADB0401D6F7D04C5E3000F0654209A8C000363C2098CC4001022484682177F0060CFA1A106100684B2AD6410CD099043CCF383CF92C88\n"
+":400FC000401047D1AA85D207C209048CFA1A78401056D564037A13D860801C481D34100188B7B181A3CADB0778F71F0A7F088476766BB492177025EC1602BFD60751A470FC\n"
+":40100000068D63D7AC6744A6077AE8647B240048F3FCFF3EBC632A2110060B9E03B7904A06247B303058314703A410F5CB5A076728D74810F5EF4A2691D06D821CA74933FB\n"
+":40104000980D0E81FF453789A471A072A060EEAA53EDF76101CFE40E0374011F4C0F27410FA80EC801E84A62F5EA888653C8700681300034035F37571F7D150F63F5880EA2\n"
+":4010800068F5D9D89BDBDAD8F599E0F3309135068177C5FBA2030E5D9F0265C1C810984020441559343ACD487C2CF243D0F45C1DE6CF01CA3F159910F0260E017F52C32297\n"
+":4010C000314D20390D23A851A5AC1050220C37C7023E8D408C4005015ED1C911581C03C270D3A5C9C8FA3C02102B0C907876D87B724C64489B86094BC513479BD188104BDC\n"
+":4011000003BEBD522268210C02FF501B91B1C3F944AC958C30B07978C648D8ED73720206E9198F46F00678011CCA8898E15F43D99947E736F109C309399C83A9921410807A\n"
+":401140004803CCD54BD25CC3E28DF18A13A3AE61841AECBDD1F50329D0C0E6BE226292009745B3101E7503BEBCC62054231047108821A36897BD41FC32C4AF6783C4EC31ED\n"
+":40118000791820F01231E980F103CBE9390DC196F5D622697C308CA0EC8D13B00E394900CFACA1446A9A4C9A4FC2E7A2454A4C8A4C27E97A63A1A1D46103DFA0233A207E2D\n"
+":4011C0000E91E23727DED2AA01E2F4410023286BD7DD47E1AAD52AB02AAD1A3E47074BEA0861D067C53400502200E1F4D2038181E2163100C230C3B3498CB408E38CFD1E9E\n"
+":401200000711A7CEF3851A20684A8589C8FE0F38BAE4D5E81040680DD3AC433299F85A74BD695320E84932EED6A110C62268A2183A64A54F56C518F41AF07524F9E0F0F699\n"
+":40124000451086E0AF0C3E40B90A8741AC242081F050AC0838314143103C6A21D5D5A6E00A7747188810A40EA81B008EFCD0620F3D0C1CDE31360058D207014B6640360DCE\n"
+":4012800016C2C0E3E5D351E82311068B016101CC0114D00CC48798A18BA0ED84194098F066608260D8365B76B6D88167890229973CC3847D2F2020D8C62D9A0158F23A59E2\n"
+":4012C000D407A0C0230C83FA892312106AC08C5EAD2819D084B04C19ECBB01960301558107D2B8E409835D9FF02138FA1A8EA3184A410360A14BD268433581606C306B1A85\n"
+":40130000E0C9A40DCB86D6C46210F838061849048C5E5AB64C0AC1C01C3A192121040A02571244711A4094591AA0593A1384C1A74C2691F6384780F41148089D0A0B4103D5\n"
+":40134000A0548B06C09688F03763F5D6010957BD0FA4618814EB81043949E17AEB8901E02209882ED2CF10029B16FA0020E1B46FDAD807A0D2720A4EDFAAEE0694182E9006\n"
+":4013800002348A55260390C60D03A4003151A352C0669020976B080EEC1D268984101040782A041EC1AF8BEFC49DE62EE208FAAF486F6A827403AB2084125D0EC97E105F92\n"
+":4013C000BD9FC7B18B440508ABB8614492340B6088800C3B86DC49009C7012FD7E60203563902C0AA23A097D9310208046185033290A4080900A22481A42144094C194D1AC\n"
+":40140000A3E878D3E003433E0F1C4D10179D838C581664C1CC427948687A84C881493103080388057C72C46C009D90E84C09858981B5568F649D1057D238A3C25BC7A9F0BE\n"
+":401440004448F4F8419E4380F433970331730C6778F009D361F1044D18017108088063885E140881B87D4246AE0582B39D9F88AA388C60C85B5020127683A4CE6A0D400D88\n"
+":401480002120541502099204F32939F3A08E0318216519A6A0181010A7D1FAC32602F48FEE24121FCA2290E0860E6A0422AF711A14B86E431A6E47D9B10835742C1A8060A9\n"
+":4014C0001C0E8C1CAFC1002CD207460F607D9F66148816634315BA86DE22059750C4068D40EF78D20F00082F52C8892079013D85F85292E6E243DDE1E277F1BED204FA67DC\n"
+":40150000E04801E4F3B3307AE468A6212DA3CBA6A9440EF3FAD1773A78C80BCC68C23C867D737E52119E409273F5D0F1750B195C1E63D7920D061C8424C76F1A729F2AA63C\n"
+":4015400010ACF62147F3CC270501433E250018AC3FCCB0944EBA4407E050F1F5ED51F48C88F6A69109850A18FFA3A9AA480D3CC9134EAA4C8A1C39DF2884E876DC9896BDEB\n"
+":40158000A8F23CEF04496E42FC33E103E169200C767409544A262291A0398D7E2372160D00AB85951100500F21E4811B82808203AE491ACD23ECCCF13528F8B7A87CFD00A6\n"
+":4015C00020A1AA10F7EF38F863EC496057BF779025816EFDDD409605E1041AB1725100C01AD0B4AC07283A6C078E825A0DAAF14016E84912018E6006BE50BAD00E621C015E\n"
+":401600003D80002A1C8178F3DFF007B4AB24023A3A71B100048847D814465A751F20DB5E006077D414E359C14840DCF17FB0807E3C141BC0C5808CCF2DF838B8CC285DE22D\n"
+":4016400000694F51C012758D889B003D890814B428D918CA173A663CB468583A0900361448E48E0841B86858390DFF03EA8C8D12C07EE91962B1401EA1001FE4A9021C40C9\n"
+":40168000BBB3007315423403515C17178A6F259C8D5896312007440A063418682A011D589CB40603E07E0B3A52F4BCA7F43DB33833DA5835007C108900368490260AA02001\n"
+":4016C0007A47E4C04188B89C06EB1304A89882FDE86A33A00122F4DC60F2BCDA8FAFF287A918C6190BBD806B184B99600220AA010049DD38C73A244801D371807DB6D026B5\n"
+":4017000004DA4082616B000960498CF8C06146172400EE8FAD23A0078844BCEE209105E1848448A81C40B097CC51020ACD620415D3518E4AF50A9978381C4CD0E5FA30A429\n"
+":401740004F507BA1B2C8F1070D80DEB2C8FD2C3AEA724103584F36807BA4C48F48C4BB811C12C3C5E447D846625D017E112D1C10626908F8210BD7E0670C022A7C475C49E1\n"
+":401780000ED0D9163969E19E40EFAEA887BF02C402F3368256740B3191045059B000C052A0C00B052CEA16690E497A24150E44D0A148990D5F7C5D0CB2268861D2998372D2\n"
+":4017C00072066162090C43D1323A17422162299D6431323A9D6421620A1622A9A0149A2151601FF154231B434F1686266884DDC77E2201223D75065889DC0474B07B090776\n"
+":401800008FDCA200622EA242C9604076E021188588B5E4D804C220D10EE71E1067A1C784283A08B02872C10006802E68030531C053142040CC0EF04101BC32034EED50406B\n"
+":401840003E077D1FE82486FFA33DCF5C87281C1083D6C944210077FA457801FE777066A438720201C77D7810088F7311103A1A237A8103C4261521141100E304770512E9AF\n"
+":401880000DE2F0B9609A006F0CD02BF680D2030A2032A363C108E3DC7FA3D92882048F02AF93750420028F9E8C6D1F4D80A003A73997452B27EB1F03F591C21EAF606072BD\n"
+":4018C0002E30AE1747CC179B12C4003084034808F582A155F0FABD8C4722A3D7D8287ABD88C8051008247EFDB003D1F2420078B748B94ED18A21A746BF225C1FFE327212AE\n"
+":40190000E01E307CFFC4A01E59069EBCEC31CC1A5403D5E8122233AC265EBCED38722F94041E1E66207F5595200695D126217531F200693D0E7EBCF13024660D140072CC6D\n"
+":401940003457094644460D3D75ECE81017068702EF826424E06C7543A8AECBBC4FCBA0D1CC612D8A103CFE0D3D75E8C847D538A279015E3C2B2F5D7AA1300715F72E636E9A\n"
+":401980003D059A20218C3C81DE2B202C32A1C5788452E68925D414A3E41C59EA0E31300B6F1221220380E1A70A793EDD3548D109FC672A25204A029201F7494AA069049E00\n"
+":4019C0003D6510901A1E90F5FE3081E679E0091AC1112C2B0F20774E6418066903A6883D1A44B1AF1C4329BB84E8BD2CA62621C21D792DA840EEC2ED40B81087BF1F9B0FFD\n"
+":401A00003A84100C7B1BFC75F05E45291048B3043B86784110489A0040D0487AF289E0F491E0F562408D983303B26E47D6E7A2CF7AD015C5C005F44228F6EB1A96892F5F86\n"
+":401A4000BB2242220EF7C1E1F055C13E834F554F17AC5887CA6B66100F067F6C7B8B1CB1747AC0E4C7EF591188F217A0047017811387E340D70E46F00B807D8FA3714BC126\n"
+":401A8000EC877C98748FF88AA0D181D3348200F261B41815B82FF100C419A21881A1DF80AF840EF29AE2217A8090FD904C061B40EE2C213C03609FBF9647872B0CB8010F4C\n"
+":401AC0004F9FA40498801184C055361012427471888220687B1E1E3FB91F04BE21E4BBE400902CCE008808A22E4A806426E89B518D23DD21F8F2038D0EAA7E1F414B895352\n"
+":401B0000185DEB1A3318B0C0EA080165800440F051B1E11744067405E8DE042390140289A1A10195848F94D711F11071978883C4224391032B60ADE020672D5C20D3CFCD9C\n"
+":401B400088F8C2B113654CBE0110151AA75F9F7FC58BE744206FCFC0A4051F50C43AF8C2B13C442038F37361028E28B2F4CC3994D67D2F18548FB16448CE8B3EC95D2239EA\n"
+":401B8000B1981EF1853A0732817CC4D40992677713F9346D2602113642438F21A9870001400712A0F4F011743CB896460047D81EA210626E33FC648C4478E9E0D31F3CBBC7\n"
+":401BC000C8318830D631E21D0720BC781B2C720309323904F85D408004022F416B180E7F97425A1C2F651E911143A78814C17A1510895FE8F644BA7878CAA1D9037040ECE4\n"
+":401C00004C030380303C16EB7261F3385970C1B12980E1081E080D90ECD0297ACC047A1C1C498010D2293D0D4A2522A9341E7558D174C191803D05882231341EF0DCF10636\n"
+":401C40006210EC82F2603EF435B8FA18FCFA5FB0AC6612202C007D04DC85E0CA018005C60DC415F32E1904A450365C718361063C1116243C9482AE4C82401FA1AFD2ECD11C\n"
+":401C8000F12400B3CAE0513A47903A86882FE8AFE2E93371F268C885C1678D180BA313CB97C6163D4008813F45838FA1AF4980A661200BB14449A003A7CD87C82BE88FC66D\n"
+":401CC00070F06178F5D44A699CA9B881BD7B4C438903D3BF2570E0885D3A3A3E862B30AE6911F80206C6AE934921CC0E8711F87643BA024E8518163350640792B3D16525D8\n"
+":401D00002829308D88E2701C7C801DE1C41192F448340601E034EA9DB3C5CC1E047A2A6C278187E86CE2E511880EA29F50028815E46F411590043AB49CBA561089E086902F\n"
+":401D40000628C8B9D00060069021E14B5162A054018140297BD0D029F5A68884409B202CCA43F515320980BC30609E00EA20BD8B1E5189F9FE48590840E0FFD0E928F8D38C\n"
+":401D8000405802896A8747AC22C4051FAA212E8865162702E88761658A860990A7033F93F14C9913C02D4C152044FEF4359A3468C0A11A8B21D2814552495142E8AC01F425\n"
+":401DC0003B309C24300F72B8194329743C0763D0A86982D5307DB8043E86B140F13C8D104EFED0ED17B1E928113500F1F4B41949D0244F00C45E28F85E30D45319B0829652\n"
+":401E0000EE1F2242237F517A1C58BC7D1C40C8E9E87E1267A5F80BC7D28418F3AF022D3A0D8880B1EACC623C1B01FF4EFB15D22008929DD59027B13428F54040F4CE08FAB5\n"
+":401E4000A75440DE9FFA2CA2B103EF30130008C20C1874006AEAEAD2C53E22861C810B7C42FA5DFC36222F5F9D8929DBB887E0096103CDE070E0E84591E8452103CD285039\n"
+":401E8000EFC861303A74F0451F3383901C5B039D429A2388540715D085DF0649895D149E41074FF6186A007A278058CCBC12AC98148D03541012480200E826701A88297FD7\n"
+":401EC000E45439566C1B87FE118100BB5418708C9091C5B208D43325A431130547786591B644025DEA303D18F2268190301503407776E0744D88F41A6880400F6DA4A390D4\n"
+":401F00001A67F1D26A17FD1C1043293072F42BD881A6B931797980E66A0305C7C97971EC43C24046E80A43EB0381F1A6C8F72B48803E8CED3E1ABA468167E32802F61022C9\n"
+":401F400003FF48D32441069C33755EFFC912AFAA2C840D34CAAECCDE2F45AC970FE81017D169843F0C0418C5D0B08376C803E6914C41001DF6AA604FB0569020B91539744D\n"
+":401F8000FD197452C990411754EC176A661C20E13F8EC9452F074E1FAACF4899980425F45C311D050C1993E6912F333CBEAEFD9628E426622291F0E93A45C05980BE4943C6\n"
+":401FC0004086E2120206D1C3EFDAA1EFDA54B8D628F7ED30F669F9DD260D7A458100D3D3A88A0AD500A1A23BDD001D76D25D45A422C06C207A251CBA81A878C3008EC0D769\n"
+":402000008A4E078D7F2A1801AC7AA1E87A80807885891488F503E91A235F10BE1F14988B0462448302513CD274797119F2E05105BC5BE65C658C8DD4071022F9D400206325\n"
+":40204000D07D63DCF5A24800FE107A134760029103D1B124168000A09A6C67FAD000C7A14C47BE67499F42A20F8A6E466E02C410087D1B0C7DBAE82CFAA30499238B143169\n"
+":4020800014049CCA244D0137CCF92221F37491A40022750329438B1DC4405E2E94100BB403C89608BB895445E34046F2B20088C450C074035DFF6C2417B06844C1E5305207\n"
+":4020C000478F27816C7112C718DE2360B8088019C5F1EBCFC802001645B31CF05C6DA2007C710F40A96C218C23C1A41C97060954C60F5025840EE9DA104B8572977381887B\n"
+":40210000843F8A1C28B048425843E152653000540163678EE6F612138F5A0FA9E34404EEC3031E39E72181A7F068A03F9FBC8544415F01AB080439981D8758201775C88840\n"
+":402140009BD918822001C77068CF2A541F650D17635F97798421E582E2F2C1916C5402C03E77740B41600611619F34EA17A3608FD1AEC90988FA35E0DAF48041E71E17A030\n"
+":40218000F788306400F008823C47C10B8D90F46BD2C1A039221CB7423C19F226A178F8692004BCE239E3D0ABC2681CD55606A9CDD097A20250D1B02A3EA7D932C388E79936\n"
+":4021C000688F1A5142C929F9FF34786E0952D11438E70A1C4774B88EB97A3800C623C0031D41A340D3F470116919AB9F428F4A454841DCF207C2F786C5221A0B20B9996169\n"
+":40220000A095132107651D8DEF60C7118E1E966E1F0C6C0F855D84171C02B05F88FFAB0E1DB99625754F0821C3748664839400040D12FFD0BB4861EE10AC0D26A34CB5E348\n"
+":40224000C7036E91EC988488508C15F47BA9CC82EDC95FCA46F2CFA3420E4290069980C3D1F12A7A34212EB61920578E4EAE1800F506898042A06812DCBD6D1EFD291E8503\n"
+":40228000902EAB841E26468785DB06C64210774191F74BB974B67892C1143900DA6A5967A5C2CB8CCD8FA34288EABB2419603AE96FB2891F468591ACDFA22F4804104B60A4\n"
+":4022C000809608610C214022E23D0208FB044C70FF87480C0F562208005B047D6CD280796A7109C01030760D3D1CA258E143A81E4A6203191CBD42E27242007854F8808B84\n"
+":40230000C00FB92F47BEE604DE00B855409BDD97F67D97F03E740A2A643D9E2826377FDA8FA38648721ABA6EA8BD1C9A3DAABC3C513C403E8CF526060F470023E848D1A937\n"
+":40234000C2E2760555EB1A22CFA38019E27528F13A733C1801273403856EFB941F470021E89492F16940D0A79480E4002C832F01E1950B10D92F08BA907EE4732986CE4368\n"
+":40238000475C4D1D1E268C5C4D58A74403756F6145880FD7B30640200F9EC09CD05D29A220A7452B081DD1C5C20B79A534BD76C6223461709FD100AC9646803FDA4D63DFEE\n"
+":4023C000F7E37B90889E2C732F27AD17A166444607332508F8E8A732EAC2F2E8E932F2D270841C43011128D8EB42213C048E79A065223D201C59D6C5E281C3F4A14110CE9B\n"
+":40240000203069E8D98795ECC8BD9D52363CC3DC2507A43B58E96E02A6E24174BC29F0C2622E0F001E8B91A06EF4BBB88045C8485CE69309A26DD100A8B2F166D11A26C999\n"
+":40244000221076F8413422185D8D423C363CBA5EB4406AA12362BACAF102AA31340D0F4A552581C22F4A500F3590E17003D12C6A9903B023E897B2024D2910043D47623D47\n"
+":4024800013285E09C31E89931F3B030F8DFD0803F64C9974FC18F5F360D4A00F207E0281C6FF1983E3E8E6D12F140A92406B034E94184480FEB02CDD6076F5B38A201765A4\n"
+":4024C000898F414C98F42EFA39CD1E85FB1F5812222482BD5C5A38E643D1BDA43D0589E6B0887C1A343C977E8E731364B900B2DA04B0703549043A23F09828152FF0009848\n"
+":40250000E9395A3B39BFB0DFCE608F728A0F7954975C8021D31C436411E388E55FC2737A39D4FD1D58444CF260CF0CD12F161E17A3968980C0D123881101AEC3674C25E8E7\n"
+":402540000C81E2AB63972A20C16182E8CCB240930970798E0C31137A47CC40DEEDA63F472E1F8AF50CB57135079F472DBA692B81E310681031F3ED9161FD01A8B2EE135158\n"
+":40258000ADE09C83BD31879719100624A172F8180051D6418E5D20AD200729931F0C1C8D8800D71A013E3CE480044386C5D0503C8B0061F565E1E1ADA208F19191044640D4\n"
+":4025C0008001F5056A396064108E631DBB43D1C80F7820B44582600A1B8B20A040208001D463E1C6C802A78121D22C860E7B2DAC41D3C090AB320B41043A82284DBEAC74FA\n"
+":40260000124C6B01FB4818B0970D0500086EC264478100068FA2A03078107D5E942789E362E1036C8C36C91F643B94EC165101D4D163C37122C7992944E1223C2A004698D2\n"
+":402640007BD509621F1A5E4F9F1C80622AC212A820BD5C011EF7661F3F6D084FD47B85272F053E91E810F8B118A084123A3BE9B4414100D9EAF0A90D3CBEF423E82BD5724A\n"
+":4026800082407896F8409F5E5B8C2981C07460812A12316008BFD87167002A68851D16464331715248B05C8503C075E25B91080E901BCE01A5DBCBE20376CDF8DDBC35E2DA\n"
+":4026C000371C0041E3C72205FBA600790AB899C08FA38CD102C3AB8189905CE0F65BA97793E1744C51F47DB22030717F3217FD25D0AEC5E41F84C10C0008F96E30840C03DE\n"
+":4027000048778141EEF2026F80304077219FF887A3E592F4DD3C93556E4689EF8EC500109D0D38F1627E9EE240D03CA0C8FD09B8868219414A01841041E971E134CEC34418\n"
+":40274000EC24D8BC6409310CD13ACB1100D23AC930A4B2EF694124C6A2C860E98F3100892103CD6BC98438094095100EA277C648A81E8029A47274411881BE6B61440EE8AF\n"
+":40278000FC42880E350E26F92287453789BE3805049841E20A9236485EAEBE9C30C25AD0E404153F004D1F72F50F40699746780FA84C07BC6B04D1243D3E84467F496A889A\n"
+":4027C00011E86FA202857E882620203B40D5F122923D349A6C017A85D30520579840C32602663B76AC580C300311B5EB09A105CADBC6008B000790F628069168BA0F7AD3E4\n"
+":40280000D44C2F230E9157C2C54FD8E003E89A82AFE0EDDD9543FF167708EC5479EABC81B13031E22D43E8CB047A48C44750A182EB9F2A1F9C1D8C2322F9CC00F3972109C5\n"
+":402840003C91CE20DF77534C84034303D197EB8D468942805440FA3EA0789448814009806813FC77EC496C3E23E8CBC5DAF465D90E0871D06160193B80F256F569E426430D\n"
+":402880008B840A01C82BBF98E9980865F0C20D8E18F9C0131D244077021D4FDE22012BDA0E420415D5EC57F7981B2131D11E1D6E2C10C0DFA32CCFC5EA4243038E1A703931\n"
+":4028C0002181D6FD19706407A32D911C14874643DA870603A321DD9F78958B00AAFBF48D481A99054C6FDD0607243C60DC2C314847A0E14478F035108263B74F4198845A25\n"
+":40290000FA32DD2050DAE9135303CDA07336D07D1ACC44AFA32D92061301940797D1C628237B417A2D146611C6F43ECCB3236AF6B2F465FA0079951246B895C50D4440F43C\n"
+":4029400065B2265429B605240BAFD190862A21E8CB8440F25A545E8C941630628055D15165E8C951F4A181B801E3D4E47EC7501094809ECBAA58CA829F49768D6B17A33419\n"
+":402980009003C1E8A2ADF0EA5F62EB4BF1D01F901D125D37964078050A552C3E90812F01D7901FE8C862ED16429518423383F29102D103A9F9F64B399A5293F4650240A773\n"
+":4029C000498A17803788312830FA08108EB636BB7DD8FD114097A22791F0AD11910905C90D044C434B79C0391F468934107A313CBA0700580385E9E487020BCE3E65E8D093\n"
+":402A0000A2C6A21D4E0E348607EA7C3E873D1F4A489635100386E8726082EC60E2E2E3422474A27162FA1120793C07F040090AF33950E7C12220F8AEF0C2C3D8CD08BB4CF8\n"
+":402A4000A11E24D63C7EB478D8014AC6CD1016C9511CC8040774769A31998E7D9F6C2C1BE87152E2095ACC0410A80D3EAAFCB2400AA302A140F6103D19FCA04897A101873C\n"
+":402A80002F4840D35A44800DD3DBC27B09FE8CFD582454008CD0280807540191210B4008CE41E91483AB067A07031360FFCF75104CD612BABECC419F467E17A3400BA1815C\n"
+":402AC00089A31F31047D19FC7742040858683D19FC403211C5C8D6CFD19FC40D10C60280D8C6DE604AF6B3797A33F8AE6A0EF4CE1E45D43E8CFE43A6A1459B95807328B4FD\n"
+":402B000074630A04111E3F8F428754299044D0D26D17DDF7244720F2681742112A707AABA0895286E988F1F1388F58EA047CE9D4311FBD19F889045B7A3410DC0804240027\n"
+":402B4000432444169080457498089185AF4900880826FA3418BCE5583D6E4C3DCD1A222711141157D27CC56A42F3BD5090838185E8CFA50B511153C63022C1289090C081E1\n"
+":402B800002012C1D82E40303619A96FEBD238633E2B130849C5328FD38207D219C6587A822C78A2491FE54F837A084A243C11465DB42C254F714C95F4002381A13624B0FFF\n"
+":402BC00051E008880306B330160505EA4222794A9CB901A8F4C220F5EAC17AC850C05EA0221F0F5389FE755EB45C75011F16020F8B020BD82704071AC0F1006887268072F6\n"
+":402C000050047E9FD62F2EB414CC06C9FE6806D840401820BA774045200D034034347C3A6E26B06BCA07C6100C935D006028F0BEB886853D91C6E68029FC341620B8800C35\n"
+":402C400005912218A005A716A8760B90C3005E801813201C20101A282D401A8DB18A580E02040A7038D10AA6100603CE62A222A94E079E005B02A82E6101C315D8610800AA\n"
+":402C8000B717253F6063901A16829D69B13EA1F912E93D13688A3C5C28C74F5737A0139E0098827B8CBD8FD04789CA0283A19F8B780FA7698400CE0E43D45FC7A3FC10C48E\n"
+":402CC0004EF5180201A13555824C23C53708922C3896421C99B8C8C43A5F70700E0928000021E1F08EB330401C018200871CF43842FF60160859E99E21124B8441DEBC4604\n"
+":402D00001030669CC0D53E00F3C82038095303B8E787AC9C8883F410111E5997C20216A19F976F90108334399068F40DA8ED7B046A9DE7B9B773181A477843ACF412D7D055\n"
+":402D40007F8316469829E7695110CB2188F735B9CA5207F97DD623A31225D90D1E4719C11A265259CFA27DB210204281001965AF849087C40E63D8E8A20F62331003C4DD64\n"
+":402D8000085FC6188CC7BA1A8BB63684D0367CEC28402063409002CAE44D534FC2BC0201F837FCC90340D3E9A981B8264D634878F59E2082008F5E4D09A06D673C8C185FCD\n"
+":402DC000D00040BE109BC4A8C180540BB30C0B134023D4A643D103C87A621100741DF3820E20A00C001A663926301A063F2022107CD32F493180BB3A423F36540847E6FD7E\n"
+":402E000022C05A0611704578F7544882E087F3672890BD69B4241CC606997C55DD6202A9CFD15725E703F210BD32E42009A65D12BE15B01F3F22A5E69A223C80C34CB69ACC\n"
+":402E4000C4B6628904A840B027CEE7025A42079600849929BCBF14382483A0C78677028923917E5CF71D00989A6569065017A7504A6892470F9B80C62888747CE06220799B\n"
+":402E8000A65417B122481431A34283CF6CE2067975107A6C3470AA00A408787A644B3F0E7D096670743A7083E6911DE3DFE13A422F3683951F3C07613B0934412075715B40\n"
+":402EC000F18512608A180D0260A818002316CFA055041D510C8042305B10494220208203A48834D020CBE34894288A024C4D3C3B595C85134C9220CBF3489088302522442F\n"
+":402F0000D323CD2236420D960217479F0912488548016C088851F134DCB0489A243A3E81751EB1FE1944300F921DF1043CFB444572C3D15745DAE787E28051F38610F0F01C\n"
+":402F400051F3C1D08E224687E64061E830940F74E58F44E590442860858882E92161136888151E252A234AC7023A9219BA22077885C88BE0382400583547202C1A084E02B5\n"
+":402F800037C39993220EA0C0119880094D01BBCA8C49303F067DFD04A6D7692C15A6A8CFD3DAA20179FFD91F0265090A6079FFDD4BAD43CFFEC2C1AC2B79B62445F35C59B9\n"
+":402FC0002940027C0927FCEE1840917A0413E038EB8374FCC9222154488264B73EF12F083A8CC6394D0802E0A79CF44C01D2C9480A607A5EB8B2E55005C4FEEE3F1E914F7F\n"
+":403000001F01F7174EB38E23910144C8F2C06C37CD066E9979D4C4421ED6BF38B130029003B96F87D2F8E3D5786900A25755BE8881C9B24B122C7831D4C2F024BAA64038D9\n"
+":403040009D468879E9DAE103071368200242EE96C61890E75AE37B90F4467177A5C8C500A38068420EC6C442343D21924071E5105E90441003D91EC4071640E66F789E022F\n"
+":40308000C765AC19A088685F695C8A107207841DC00090448F49DC100D80291F154D106BECAEA9DCE44C20F38E78B1873E0288623D102A82FF2C3C1089E71AB1137CE3388E\n"
+":4030C000226F5E51201A8D88F9C410C994BA483882CC4908783848BB8EC8BD6910979FCB0C9868444728F8BC16B844B7A7788894470200EB0E2F0291861D149A98121299DD\n"
+":4031000040A899D952422901E7500377001D9DF57739CCC881A6D52C300F9A020B14F000D10FDABA63A111440B0742318F9156901A5B48482315828F0D341F479F979A6E36\n"
+":4031400044D6980AF5208A1EF708364D1360B8120B7F01BC8F823947C52EC4027ABEFD1028D734C9F0189E09BAB69C44D1F4AEE373E3D3F54401F54028E5F00F961144A2BF\n"
+":40318000CB4B22D806B0A013C13C73C900E4F811C68907C14DE409F82530AC58405883E2D262A2480140E84871A148C8124C22A2487703C0F90B9468900649844C733B46D9\n"
+":4031C000280B9123A4BE0ACA004F0517BB888169619DD20154ACB200513C14C7243287B9FDE2EBEB6893018A90CF960222070AD0A1D3E6CA74E5B8B137C60E52EC41E124EF\n"
+":40320000210415216CD5049F9DB6D421403F3B6D384F041E97C42F3B6CA40610D66D419097C0D08778905292D1890C407592F1B019280340B76F2C0F6BD28F815C881E8993\n"
+":4032400021DC0843D2B602C014A0072F4780261674310EE4162450E96B0128B2340BAF998B1239047E087A2EAC5B1EF7741EC1BA1EF3EA1BC0C331C87CFEB886942070ED6C\n"
+":4032800001820793D1240675D1B8B1AA9F163D202A2C1149F87E48AF671390F2C5641DF4CE20790B64D029828F3D7A0816C79D980FBF2F878F0F89AC2EA04D1A30406481A6\n"
+":4032C000E2D4A4C603D9008EF301D83EC410F08A389FDDFB0A44866CC081C150679C1A3A0F2235453F2EA208240601A120C85AA1C7C344C43C014C1C100AF1BDE1034F6948\n"
+":4033000008F36FC1EC79F2CAE6289446A9514940D711C24030A41038B9520019D2079480E84A9E0AD21C072C25280067501E4621D7B4C2C71F4E1E7DD65C8DA07B46607A25\n"
+":403340008A38C39EA2F443A82B08BAF3B4588206C100401E45679DA25202EE01321BA1DB87C78847E00983E8DD4163C92263EC38F238A3CEE7C810BCED14A79DA20821F5A0\n"
+":40338000DA6A1E76DF100CF303C140742B68CB0822943D1000189A00DF259523ABA3C9C5814486EBB01263C50EE59D3C5D1706219758D8092243521008AF3003C4F62180B9\n"
+":4033C00020284500411A06038845E07591093D0810A02DAA802289A27355085AB3843D33CC61A6438242174B88CF4C1A21C6EA8421EA36413472D9CBB9BEC7C4DC62689E56\n"
+":40340000FCA4790D7C30EB2C0707D080E40847CA148B19089E4409C1CA13D2344F0245025736FCBCA546392863D457A394B62761118C04BB7CD079495930793042782D54F6\n"
+":403440008C110480D130886A02F288E4034F0DEF97520C0F806107D1F763CA4DCBBBAB50F3BFD979DB8C4DC358DFEFB081150160A81115C2C1002023C160A01114FBA1F885\n"
+":403480004910582C047CCFE42C11A3C1E7DC38426C0F059C188A1D81CC5DBB523E62C911C40BEBD642B3510E20412C0BC4001231560963B52E325A36931EB66820241A906B\n"
+":4034C000238D6C581093E57EA3211024368640DEE4BD0897C481EC2BFA0AA4481C5F64041CD2A2EFCB81EB1791F3CAD99AD1043F313F881E3F1A61302A0AD41472190102C5\n"
+":403500002F003EBDB72EBBFA2022F003058129526512980866B014BCBEE444C0416E84B30045B1EBAFBECBD23386395B810D2BF1C410C49F72D588216DF48081393EADF386\n"
+":4035400019C867F0700F93D30F89833A00C05FFB5C14BA42307D36BA5A5B21080C2ED82F299C484ED83140D622AB2848AF196E17404D09D3C545C4401A029CF693CF1A12E0\n"
+":403580009BA23587A0380BAB845322AE692B1F88C64304435813C73B1229BAA568473B9451EADD61C414364C0F0A54A1A3EA3B9F51C0208F840E8BAD7767D4B7E2C10011DE\n"
+":4035C00010453101EDC7A124C4FF4BDB880DBBBE8F89410862288C6208C71F4E50980E240CE28867EA9FC2208681F4C508C0E2004328828EC60B2208291ECA5AC70B5101EE\n"
+":403600004404F87F34C6534C5624814C1C40491AD9C202601643A74A0691A62A0F2029240A926307A2970A2CBCE00281A227DFC40590EBE70CC1138B20D94005F08839CD74\n"
+":40364000007610A5184E812007A00C9F88820347E397D6CCE9484082038A20B61C4C0529100DCC9062014457C411ABEBFA4100C8334441B3D0941E703422C4A08B30FBCFE9\n"
+":4036800072A200C4A250A80743C0CA81893DFA1C221B051521208C05DB9F842D60E0A8012888030C82048A23CBCE3365E70DD2208F3F386F1507133D01CD80E83C23D6E5F0\n"
+":4036C0002221A73181043A9445A4389069CC42069A6129279CBC2511ABE5AD4107B9350081C4B1800719E0993FD7D9E56710244CCF38A50F9C50849150AA00E56603201FD5\n"
+":403700003865116266A7478444E40E2270642A1F6BF82394CC986998BC885CDE42E2BE9BF82312E2010811C05C580D0C44489CC86A572A60860200A1F697E8F1C65120817A\n"
+":403740007288F7A5C99F0A35EC0C170A05C8F080940E24C8DF388D13052A05D1446C84A8244CD06868ED2DA18931E00F3546135861238EC234A009EC203E736A3AAD005C1B\n"
+":40378000AE2B2B20981DD38803405A6393CE082C0C02066F7E828B05883161030747B397D04D646CF4EA59F8AD18452E412A45107BE7151306133404FB10802C0CF9C57593\n"
+":4037C00008B30653E92A711288207C85ADD3288BF4E5C223101E0FFE1E292C20692011489110C9528021F38A10961577020D901024063AEE40B028D33543D89119148A46FF\n"
+":4038000001CA8656452AE20466249421D026067C63D05814DDFACC45808F1246905D140490F24863E501A3D6F16A1A415104300F63E91029176604529D8A665B18DC88450B\n"
+":4038400040E47961F3008FD6436800C42867EAB524020E4B6E5E69022E4DB05AD5A107888B8A84D0074E12007A3039654083870F2CA918302A020F13AD18360507410FA939\n"
+":403880006A44D10489100BCFA0A45C14658805A5824B08B05780978911DE718C54348A137121E3C3E08A8E48E8E78B0A315E6C5970041A848C8162CF86C38D93D523D12167\n"
+":4038C000A859E715E6CB648F47A740398F260230A02C0BC330D83D3C202843114471244C13C553C05D17C6188318C671B0711D87B200852288E24C96267CE2BF25495C5A1D\n"
+":403900009726018E70000318B6781983D884781943D0D83985E7818DE71591C0001CEFB84F00AFCE2B277CB817CE07B2843816CE07828816050379DCE2C02AA0190379D85E\n"
+":4039400062C01E3D888781483D88A781443D88E78141D234C2619E04F0F639440935D24125C56B44963A87F3C007F38AA21E87321C1F20476935848C1EC583C08A1EC5A3AE\n"
+":40398000C0881EC593C0861CC50EC59123C082AEF2AEE23C07E892ED68323C0788544CB3C07452328F01B99198780D4C8CD40C8C8C53C2ECF06023F38AA90B912899C7800A\n"
+":4039C000ACD106780A9929030602879E8004713C04E02F06F01C1E715230DA10DB2B81B381406320121E23C455C2C0AE40221CA041038A2F0B60C94A0704C0EC9498344372\n"
+":403A00006F38A5A37CE05450136A3E714B136A1C4937E3D10045B00CD07E0738AFE0B03DCC080125B55517B3F94A203A7C450C0EA019B81AA0D818690381079C56D305B377\n"
+":403A4000DEC44F3C45FC83031490D0CA2809922177AA3707319C7CCDBE46FE9FB4790FC881E6B74F94882C190220896C0C9AA06DCE1010941CB118BDA7D2381A0021F0EA94\n"
+":403A8000E97631E0901EAE9C1080B606703508508FB7840A10B13D1683C08353934D24B7A88FC4FC47B122441FE4EFCD813EA1E313934D245E853B1034D0018180C804111A\n"
+":403AC0003C8AD08067DD9089F8CA88FB15A8B18586BD904D73F393940809DCFC43E79301340FA24029F1A2E243A851DF7F227D97A147AF00C871263BD0A44F721C440B3132\n"
+":403B0000B10087E884C920BB4C08F17741E1E6F101038ED014EB214D33BA144083B48642280ED4804E3B942307B5B31021C211E4D52C4018320089DA021D7B44886552CA83\n"
+":403B40001AA6E94A0196A22F9B3B0402294241E8503A009F3C5088428106681BA0617D93BC262F51AA09B848199DDC124079647E9DE3C1A0528025A989DF02650A07F9A290\n"
+":403B8000730024A80AC1F3D53F0800424D2F43AA561132833E3AD0467100007B33E04C51C81AEA5E912788600C86186990E1760607B2D610442F40DC880C0E04049F8B9E91\n"
+":403BC00004782D4B0385000FD7A2031E39A1425D540A839051D74E22C17480481790043FA83BC9921902EC29A801109400734EE5E8282991798E78413F26AD48207590C30A\n"
+":403C0000D9DE6A969E6EB0102C0CEAD3C1A8612C883280F13C4D52C47BF13280B7EC7B13F1E334867C6070CD2278821847BBFE40A124C20F54DC0D6E06C0DE2048260093DC\n"
+":403C4000E4905581780B20A8D229A2C0FF338011F6E8C40083FA100D728CDE004AF303B11A88782C0FF3C513488F24805F2F438E173027BBB43C89202B4F2E24E151D16E8D\n"
+":403C80004257B0548000086B2C2EEE7E40D32149311791368DF8102274EA40884041E240791C3478FAD1767298851C7DC91F53AC90C1EB3241238A8283D4EB881A044428DF\n"
+":403CC000913042461A246150C7B548CC0DF6E2C9014431FE37F65AFC9CA19F45EB0900144101D24B78E8E44032ECE5EA3352F4A4111A44264AC08BC410A538810428940223\n"
+":403D0000EF8822CC02F0FF78F2AD412803DEA09C11F490094D018BD5A0023E23E388A3BC5C0263405E8811E147C2AD453681AA3B01A2F04A3011BD6E1B35D2056F18CE132F\n"
+":403D40004455F424F1771639162051E8061A4317A9EA46BB4062E996B317B50BA455040680A9D8CBC55E2186048D019F8F7726337A9F04C5544D9F48108F73298815CA2658\n"
+":403D80008454D43A8F54EE8D9D04502A020E3DDC4609499BA25DD9A888B440FAD3207B480C981650280C0003B8334BC700C2C00E7A86610488BADD2D0F66A10881E74666EB\n"
+":403DC000AEAA0B82E301BC7A9400AC3216FC0AE68EE42A11A40107CD50B885F40C520230104F03989B8068F3FA08FA9D7C7AEF8440104F5C71361880C347D66688853D8459\n"
+":403E0000BCB4754220067164004C037268C397648908801A2068075262AA10B9F825820114025CD680102553710DAE4F400715D0CE7644D10CB3C50676002002137931D1F8\n"
+":403E40001A218729182F6B371861EAF162E41024780B5A2E24007F6BA423E266E3F13391667D08099E043C3E18838CBB810104EF179B371817CE0951B39496F96F21C133DF\n"
+":403E8000D13B48731C02CB202E400841C137300940883A427AE091407705F1030CEC4305B10810427C23D21FB3D7523310231C20849AFA240213C11EB75A394080839C6059\n"
+":403EC000850C8017ED0DFC13E08CA13C18E53C05D4F8E45004C7881FC9A38C3CCF031098E9254E804BB83D470D6000DC8404CFE06CA0500240E0FBCBD312D00A799FE6798D\n"
+":403F0000FE6100A77C1800A75F8DFB16D7E8096167E31C796289DD810699AA387A953C80B1E0FD3080F0881E102188081A383B1C9F219F68BC10F4198006B0D26A8D3E0E7D\n"
+":403F4000C31C9A31298E003CF607BC657C3CB95C805306AF40A5F1CFC10C7C99CCC63F716B1CA02F060F05F220307A9A71517913545E50BCC3D514664AFAA5A10144D116CE\n"
+":403F8000D64D0163CF4A821E808281AC2BF8D9247A1D2440C19A960170021A22A79326C7CF4E2981829451F9C2E47CF4E480182144189A8F9545CA7111353F532B2DEA69B9\n"
+":403FC000F2834C484C95F535C20189A21DAD722132109808101098082D3D4D30F2FB6F3D859500443A835439560E1B06ED8366C1AFA9AC910D14C0416433F07002628F4299\n"
+":404000007121EA68A309BD80BC8FA9F78BD4D50D74B05178EA992D3521794290CB44434F54702BEA6AA6BB92309FD7DFBF736CC1F327998143204400F2EB644A6003564A25\n"
+":404040002048D5EB36B130801003C79864689C7D369887B15147005410A0103868DC86206E8C087C6BD026FD7C8FABD5870C289BE681C0108B201F8AFA46203B314040D3EF\n"
+":4040800048DE851F42B28C41419312011CC48D8FEC4DFDD6388A0114D33798090D2378A2182088D3920C60146204C4069F43C291C05194133100861C9C9860060090B0301B\n"
+":4040C0004CE6C1BD0A4011CB57C05009F45041208880344DCEAAA6122D13C7416642B067D79F02699B1EC3881363AE72130B3B05F88E1213C23F237CC804C6CF87CC47C036\n"
+":40410000ADE3E8D6531E824F4BF291AA689E4051A4689142079870C41036982B840F3A0D090052A06919A490803C88814EA678836344C9980009196E520364082BBC8C5FBB\n"
+":4041400025C901D533C335018DCB85C8E901668260242390348BF3A406EF04E1F3E418B0101AA6002A2A82040F81664E2930549A044010242100C1E880F1CDA081BD747E4D\n"
+":40418000247799500AEE283B406EBA452F329F14B04AE21440F1461A2010F4131A258122607A0AC50297B091040137BCF51823101C1C8243AF55AF181FE7A8D4BCCA56A143\n"
+":4041C000B2604EA0C003339365C9345C90B0C4DD3409843DA25843C04851ED6F6371410104B54E01A048111C7F0CFB92488D01EC80F16FD89A04A033E81D82007C6248893B\n"
+":40420000FD711206B1204F280E5E5B092A9A016EFFD0BF28091D5E609002279537C7BC2CC88234C893888435C89E74DE358E1DCAEC4081B1D3D3336950F4370890C4C041EB\n"
+":40424000E3BD94878038D12109908100500DC27F1E628F12AF00989A03F931E77821364101E4BA2AC202BC201E0B8E66505A96E12E0790B8D71C30AA002FDC5212C7A268CA\n"
+":4042800087999C11C444045D945E40582FE075F1087C529A90824197C79018680E06DFAEAC04A3023947908C7C80A04123406E28413AC703406DF49B38FAB5ACBBAA787AC5\n"
+":4042C000F66C40CE962D10607804C0F2881BF07C04EA3290F724C0945CB7ACC0A98101E0B32E0CEE3E326029B431F891444322881305C5B25F2704842E8FA71204B9310EB3\n"
+":40430000140683F4BF310B8313A5C2489E40E7007C14643747009E4D0808181DB6C043D6D82221011C3905E731081372B1C13D3D39E22011830400181C5D09BDB70E21603F\n"
+":40434000E4446A314441F1BC810E227783D948711087E340BE04309A80F462946248F2181AC221461579A5BCA842196FA3923E23F85C4F764E00C3075F2C8C38EAF6642C7D\n"
+":40438000EE21323C076B8B10070F4CA46433218BBDB70BAC268855B8404422411EB09E20E03847C390C41C7B8FD840FE47B457D50823B1070827282C6642065F3022577864\n"
+":4043C0001E14A0437CC6010DF29B84151319EBCFC20F6585D92305D82C08F7437179B10884B1F042D9CD8AFA82F316E27C01D6BAEB90BCCA6C975D7E174F59175746103901\n"
+":40440000A4EC47BC1C0CB8478051906F730086FE18741E14E02C314904372DBCC5E843F9F63FF633B0C11033DD4D8880DD05582061D40DE81DC40D2A81BD7B608D05E773C5\n"
+":40444000E989B51064D03687642C8F83A207CD3D445B0605B797340C062C432540384A0CBAB3610C2A80379200D7424E880BE5FE02F2F868821D7A445CA900B979011308F1\n"
+":4044800059A08D62E4960007A0B22072C2448E103D7ABA830C72F262BF2489B180963847B033CC704878C7CC59F5D8F0F993A8BC6506260F7082091E529C85280E3D0CBDB3\n"
+":4044C000C10C452F98E0C7A45F46FD80E6884330013A061AE52781BAC719180C1CA7988B8140B81972E1840F354A02943C27FD17163E6DC9202E930B35EE16BB027C0B25ED\n"
+":40450000BCDBA460598D1288244F8192244B6520409F0359144BF2B7A8F56680847E734218E1003CA8B821EB030970667AF0B88B8F32BC100A6810E5287D6AB0F40FB88E3D\n"
+":40454000BDFACE41978F9584D720FDA2C85CC3D840EED5C9221BAD49C79A9E1692384993D80103C220C8E0E433847691E0B01B2202BBC695250600693C873767103D127B6B\n"
+":40458000D010A24F77FFE0CC07E775512B80CB560F819E449905EB72099060B600699004398B02680D844041349589A0D21AFB0DED2B780134C74EEE178E058AB6C0B930EE\n"
+":4045C00058F20268972029755300129A2319A631F985A0F00A88FA1397AC7B8CBCB234C45FEB7A0224C622F40AF37122221FB04104A5E91661117CDC3081B037F95C8C8050\n"
+":40460000438432CFE6405A840EB2C1202C1208BD70523E9887234052ECC07112CF60040E14A9421A6EA104FCAA0C669A04F1AFD94D23DA7CA443E72F98142F551972D0E13C\n"
+":40464000240D612086C52407F065E5CB3321819030F6852F0D0808C27B21DC37420610E00C9CC2E5225486032DF112112AB42F420D018654298045A81A43D660C90C0652EC\n"
+":4046800024117638154D7A895858C353051353501F1DC470207582C09DF35B0179AF705810D036D875C8B096A378140159B080A30919000D06E13A07012794419656744449\n"
+":4046C000811F8D32D4301FA750347D07587E16421A5660F801E9DA52D90588C0E4FB1248F49D9181199CE220143EA96E10CB97871F992712CA4E2C7BC3E66EE312C78D9BB7\n"
+":40470000B0428473980BA8928BCDBF4B76427106F92B42070988ED93F4C0A880DFCBED8B1A884D00699E6691E64D8004D0404D697B44D03C8982A8983B337504402408D300\n"
+":4047400044F0ED33F1390BD108A12809B284662F8982AF5B9C31631489424D144C7B7C8C4653F629589030C9A28C983B62D96183110290983B9D14883149A294983BDD140A\n"
+":40478000A83189A2990783A29903393423A0111887AEB48F163911A4F5CC919420380458D4311A063FA5010B632A33F722184FEF3300173D252207B90D075B1E974F99A0A7\n"
+":4047C0001108D8EAC0B8F2E8D8F98ED87CC7A63E63C531F12F2FA01305DAD7937290C7E60193A182560E26D0E45D0E64D76BA39045EA15F21011D25818888FB565C981206E\n"
+":4048000031B6389A25378574880BB0909B40C7963350CCE2103BA6A28B33D07C9E003A82B2E970E1105AEC1711D55717287A2D568972C562EC1C51EA1131C61E1A44B1F4D7\n"
+":40484000EB20CC42C780EB84CA1C8AAF22C997B9F54D868400389E08CE0440447934C858F269B0823E4E042F706D088C1881EC08418F7F8C17937FC7B2588C2F03C8206C91\n"
+":4048800020F26FF25DBFDA87352F1EE128404A1D4F1C9AE407B1EC0F074131887BF26DE0CB02F2100C4013A48604C52831D65E17936F88021ED0E7A3620E8083178B08C4D5\n"
+":4048C0001B0128E00911C244026274848131420C7C5F5825EF97D887C9BA0C8CAB61179365CCE201FC9B2C87935E8C0453000B3BBC12D3608801E8F731B8AC7BB0910F3297\n"
+":40490000413CBB7841896DF4D20197404EC69E388FC0D11149807099D0278F995F44CC4F29CC7CC7FC35DE0690845100304041793D30BD031EA752138F82CE8A9020348A1E\n"
+":404940009D8CAE20A9038E3408601002F21A108023D80C5D80FE501D234836268603442826BBD8744B10049A008B1008D00CC98EE6323AAF0348312C4638E08D1016304685\n"
+":4049800046006402E66588CE7F84E680598C04CDD401EEDE071F31D9884026FA38B8C29F2F1E0E6DB88430E3DC4DA5E67042A1E069849E8068109250597A8226F63A1970EA\n"
+":4049C0004AC9087D56F0617CB12F5F329798BA4424346980843224029EE5C510CB642020302CC76086AAB07CC778398908041988C202108D0B08F522B1910CDFE82306D450\n"
+":404A0000B9596985D9B792C01A162222601E1F71E88F98ED90F30DB21E63C23F30DC2977809B451F9C428989F130BFCC6285C9E698038AA0C880E66145E616C40D633B39B8\n"
+":404A4000244513D804340CD2D816BFCC2B342FD42203A7C9C84436BB3AE081E275036BA6BB50BC884E2007997F9F2AD3227F1C786BE350F30DC09825D03DE7B382354BEEFA\n"
+":404A8000D086120C85098EB014150A41020CEB208B9286348B934079117CC61C610810308040F1AE5B12E0A9A25B685AC41A0C8A0C6702248080813C09F97D2CBA1A04BC46\n"
+":404AC00014423E5C0F1C76A00D841E5F4630E897053CE7E834243DA7AE407F9DDD889704E204CA51F2DE1098BE1D0B9F6FFF8EBEA47CC3E660306219101CC93932B90A5E1F\n"
+":404B00008D8E48F601FCC3CE98360719C11781F7C7A0EC44CF08750483E9DAE2BBD07CF9363D32325B2E98ED4EA43F065D596A25C1945C79E1F46567EDB983014F50C8A0E4\n"
+":404B4000EBDAE60C12A01B3835EB43D7B4481E0A07E0F418C4227C0F218FA86E8A1D13D3AF5A8A24C41EBD6D630090DDE00407903F91003CC2BA9F548F8B05279856511B3B\n"
+":404B80001449238180D2AAE281A47839EBC889210BCC6F4223F9952887BF191B08F7E6359134063CCD211E4DD18CBB318BB02305F8798E144C6EB5032ABE0ED5E81050A5A5\n"
+":404BC000ECA4F1083B2F2C42037FB8ED48D1ED30B13C058D02C1121D7E40776801A62ADDA245C84F7651126611701405C010202B12661F2CD412061458BC480270BC2530A7\n"
+":404C000046737C7F0E89B09797448824308B3D70B620878511C826022300D6123D848C44F02206885526167E01C86AEC8C52F30AE2188705AE71E62018D01D04CC046601E0\n"
+":404C400077D5502447DDDD03F8CA529CC6B878479C1A00A2D719099C3D80A528CE0B046081060B5A980802EC08F392C8F971C0FCB2703E614612973C307BC6CC716F413E52\n"
+":404C800052F26C113402D24072240D32ECCBF2E5011200A79998058B030CCE16C300A4D70ABCC2864C50C033BCC282645A8114C0C32ED1D2BD026997CC17C898A52F9845E5\n"
+":404CC00047CC226D1A60E14A08F5AA889D68020088E8008AA12F98449104C220045326FBA4284F6312E950250D23D028F69F90810780B3E068633091C32C1D938886412131\n"
+":404D00006BB50982C2FE8479752220A109E615653CB1B459CA45D8A845A2982C36C1D7B6C4060241973BB11F69D8A1CBF0C7ACB18620C3AD4C41047AFDE475FBA2060167A0\n"
+":404D40005461748A2889DED0492D9864C5FD2D091C03F016694681B23FF432E08140598D3321DD2B025F4290EDEE67722C9BE91E121F8CF2F8081E4C5F2C5F15A587CC2A79\n"
+":404D8000C2528AA6895E4C8064C884A7E0614160BA336AD85866AC84A9F30A888A84818890AA519804820D029BAD544460D54D09D2417B61CC80FD879C48326EE1D0288B97\n"
+":404DC000810C7E154A6F30A609A6504903CC29452122210C19246B13BDA5A020F8062F1A3EDC29125BCC294433036102A013995620D72E7D1F30A59F985292F30A3AB70028\n"
+":404E0000A4E04B2A12CC0A5063C14DA2C01861045CBABC48EF30A422528324B240615D1451204B798525129500513E37B9123982E120A18013E36411259C0A543A06F8651A\n"
+":404E4000403D264779851D12941C25940A5412C070182F469F98520CB9260B92663C7CC294A0CEABE5A2A1195B295447DB8512B7021DA486222142C597E022E916420FAD35\n"
+":404E8000EC0680B7DF1F2860863306D6C56B503C81E3A09CE621844A807D003C2077A22C440327405D6728C2000A4EA1E71A812882308214B59DC508572A016BE9A3011EE1\n"
+":404EC00001D9181E0109D24E9D00EF4CD00CB4862481D640E0F21E0F1820606A96112C0113A12A1EA6421969836A1380B0018142779FFCA4190CB985709A01BFA382CFD7F2\n"
+":404F0000102800DEADDE1B8DC7D5BC258DA6023E7B10441064801825049A6581244093A004244AB3C3631C1D58F223BA963480243CA7CA200F9910442034823E5208A12507\n"
+":404F4000CE3FC793BC8807E6383222C604BB36D2460360D607BC8D56443791BB0BA6A50BBB2986183D2972654FA7FBC401F6F5F176A6E8DC1E07EF6F8010FE029B40EF2500\n"
+":404F8000971394790F6B9C3CD9B4780A42A940550CB9FD91F612F23E629C1F31481798A2CBCC218D67FB221123CE320C14F50B21065DD5183EB8CF22EC8D21425340DB36F2\n"
+":404FC000827200ECE55C2202ED5602675C841DC4D422F104137A821C4251E464038E32404101CF10CB334840F1D832103D2638B1AE6791E069AC66F907A08D533495EAD009\n"
+":40500000A4470D7330E42609276C91F0AC4080862C20927DE912370781C9D8989208FBA004ACEE07904F2C0F216B09241302A08803EE4399C8A310BC9147BBDE842203CF97\n"
+":40504000A0CBCF7AE3607028BC48CE2790792311D4003488F0B486F06D08847D8F7A2C7707210823C084079AD230E8D1C12887DF74790F461289750427B9DA0DF31B3110F1\n"
+":405080003644C30181AD6F89F893F058882C54E0DEC14E2026A1950004FF4049DC92A7221C7C3D0E32140D64FC831E80FA5E14C56E25F100086B30980C6CA1CB0291F46231\n"
+":4050C000D0F8B53C7C8B683E25371EDA702C958103713F0924381167F97468920408AE156B0D8BB9F6040C2F81ACF3A2EDD792287C8AFC89104002FAC4543C436421E10079\n"
+":405100000776EB2CC847BE5890AA85FA243C7AD2BC8FF298D21E07602012F334C09D013C18FADD344B010BBB7BC423C936407040B90B2AA848338402EE1481DC72A618483E\n"
+":405140001C1F604179F0FC42BEF77D1F12EE899E43F800BC47709C7F28BA10184F12004203AE800EF1A11F023788CC4003474019ED9DC1360A2047BF234882D7370FAFE212\n"
+":405180000485CD4E1F6FF4CD9BC3988017294E1202FF04796BA284B06487902C0403EFF8C444B43C04CA23E9807A049E1F4B1060D213BB18FD220BB24B488EAA323444D170\n"
+":4051C000F413047C8F783DB9F8979B01C43E3D00EF41CE8EA6FC4960E40B1AA445EDEA72CB981C05400980A508643078D58910A98E76AA3972E20B9AA1ED4BA21C254CC0EA\n"
+":405200003A671B390040793BD8E3826B063DA504216816134510CE0F93A0D90C17171E1D96205A2080513432F730C8E3CA33890100D60A08E034D109B37504B21D469044E1\n"
+":405240004CEA203128C0E0981B080D009FA611872E74CD20849200FBEC38C912382DF1C370925DA81C5290020ED2005088103C00E79F82688324087474A1E30641C0CE45D2\n"
+":4052800000CA4E94BE017010CB96AF202956E2A5F760B691A0069AA07921E3BD21F2E3D0E0000B8820F804011F45BA88A1D466624820041000D7A4F413EC12113C01AC2FB7\n"
+":4052C00083930C206697B0880F5B73280F617C2D1F617A8B58C16F21AE90C77B7199A8792A20FBD0A442137F29904850DC1E130100094C850FB470E5AB3911000A11AC5650\n"
+":405300005E04C71CF8B541B2E0B3D564981A4D1FE77EAD207C4AF63CB56442CEA6FD2384802203CF558F8999E71E91048E920F14F8817E2E071080E91F7AB920A87201C1B7\n"
+":4053400031E938912D0B0108A83F33E8CBAB43076147121B9B240EA59C4403A08EF19670823D47EE4389D40499D3E18740F0900A6CC38243061DEB92474EB1186671601485\n"
+":40538000D6B3894C187B9FE48091CAB44BC9C3E5E4F3430AA28C5E4FCFF6024F7268812F0B0F740698122545101BEDA8B11D7BB4EA7A9AC4F4ACA3EEEE74441EE8A7120BC7\n"
+":4053C00060A22D4CA0F93EB87BDAA24C42D901D40A1F4421F7B5E244B3F68E61021E1CB420243AA125AD001E8E55103032AFA0F37700D24036BB86D04160285D0C01105877\n"
+":405400004DEA99B10AB9D458B1A78748F208886057C95D05688021814F092990107D4C05AFF621E811344B0EB7B62EB0109F30E84961E4C9B19EC07A0081E03B12C0428B7F\n"
+":405440001A6122E5D6C5102022009042096B0B841306CD42D08421BD2E0E20416D4090E757A3E1F2E3022A010658C6FE249756D597567014C65EA56442E5930EFCDA162076\n"
+":405480009860080283078721500203E951F31B91C35C1DFAF63E1F891980BC9CA25388D4B08100F271053D816C2078CCE481B270B3302B84013253D4E3A6C310432F23406B\n"
+":4054C0007CC7DA2541A03FF6301895BE599611F87102898EC50C23881ACE0E1EC2683D5FB0F2B141F05EB0F8D2F041BDA05CCC68E3F64AB08E1D5B40575587AB274403EB17\n"
+":405500007CF230313B08CBAEC41103B09DCBC73147D25B8278060050AA100213B881E3F945DA16221ED6315EBC12F2B29A5E2916138C1B3A25E0069CE4B085B1C79784592D\n"
+":405540000A712F649490F278B1E63051E9BD419947C73A220553623C008F64EA96D54E539156B103C2682C017A2D10AA38AD705B1280D491E29D063DD3C47E1ED7301AC9D5\n"
+":405580002571705002034F7C3B60040FFE5B6712BB14F1798CA8C41F475220050440D841AF082F1BBB4881E66614309816B000A652DC7AA441ED9193999724042F65AE1178\n"
+":4055C0004C5A14C0AF6492A0071B40D6B8C47C3A6E3348F7F7F9DA14C0E30A2C99871034F0EBE07102807B1B85A6407008BDD2F263953842898F74179003526868160AF6FF\n"
+":405600002101276400D3EC9338BC3EB8566219980764FCCA3E3669036BBFCD12F12059825E12EE29E111493B4A05012EE8A8116401178F0062E1E2B88873CB88A74745CCC1\n"
+":4056400059BBC41C64D30F74B5CDC5C3043B13717A1240870DA07CB9EC8881D46CFB26A06184024C7202025F130E8DA0C2A5007112B65102BD28B02514E4271A32B42FFB38\n"
+":4056800086F9EAA09A554E414000780C71E20C80287B83DC80D2EA3912D930A8C0F0E6E0F8E65CB4C24219FB2BD884B21F607B2F74118C9C24C24729114B0A368762F0FB35\n"
+":4056C000F8968000143BFB0BB240B09485F1AC308339712412933DA58657F708555484040B6037A65346AB080DB001EC956555899D8A002551901A19273C0550A53D220D9B\n"
+":405700002902CB0A8C0043D967C74300F12413900039C5398700D0C8841CEF3731F2CBE8DAD204C04CC203C5E09020B1D94F804003373B114DB206A040865D3AA490BC19A6\n"
+":40574000287696F882A480078D78F00B8146802A9EFE771F014B89A208912169C241682DA40BD08F11A20691379D99A2061020B9BE007A3B3522043EDBA4847EAC847DC922\n"
+":405780000C7D66B8876855968F2080CD7A718181353A2BBD17D13F0D69901E591FE57F4EB7164D90DDB420408C7F99FD72B267B54D1945755217540D93C00EA6A7EC8AF138\n"
+":4057C000F6B829FB7D9C40C01A7B21DF9687CF8A3EC4E5200521DC3AF3ED320029C21978F05143A4D13A8800689129E5600782DE1DE72E737E7DC30F2029CB4F40D0394DEE\n"
+":405800001E95DB16188310B4D9057981E0884681CA500806D7B6EF27CB13C2039B04FF8C8007ACF2106BB405079E478F8D14D0F77588805D5D3424072E0744AD47DA6F033B\n"
+":40584000CB8C49860D528728307C94423D730020C858006E4D46C00C19041E343C40D533CAD072484689964008DEAB731AB7118058EA6D71332A64407EF1EA120C83024BFB\n"
+":40588000A184A302B382C4532344C1ABC69C66000CC568184681B7E589645099588D808100B4DD84061FD5301E05C0113C0E04C133176F091213A79984C4F2F1C973C9E14D\n"
+":4058C000294D9F2285118BE22A8122372571034AD0300D3A81A60D02CF3ED4CE5A8A480CAFA47C833A22BD0223A80F34CA124C0AF1581274A0182CC0ABA2406A0247A040E3\n"
+":40590000B505E8101E867018474F006FED30C2681444006FD6B8C574825E3B389004BF23C0A13AB08072E823712140DE88E61C63C0214396C6F83CBEC47B844841100084AF\n"
+":4059400002BBA0D07AD880444F0598977FA10FA44CC7BA0E0AA202EDA0F23BA11A245F748889246811155C03F80817882499FC7901FD93E0236FA3C3C4621E851A6C207F4F\n"
+":4059800051E889803C022800E0020A5304770A30CE01B204763688F747B9E1A5028801EC051114CD71EAFBC88E0ED6821227C9B962331AC3B15E06F5D350E2CF23ED1CF36B\n"
+":4059C000C1C50E0540159CFF3E8F4028B33DD2EB6B8160A9890E6ED445804008DF547B48120C0AD87784A90085205C1DEC472434DA4341C3C3E543DBBB62328F02110A2319\n"
+":405A000010A63EBD5249360681E8C2A1C26A10BD1DE54288F6616CD427B3988F57C288C5B5CD95408975D15FE3DC9E436FF0031006BA2BFC767972F59AA10F26881228F653\n"
+":405A400078556CD72402805EBE552D7B988663C0A80487D6642EA8F01EA46B10303694979FF90C33ED35C100C1F074151081D0B815113AA8686BD0083872F4807972C4A2E6\n"
+":405A80002BC1DD1CD19BB67653D2D4220B9D0480146F1FE47F7693114A0702A1EF321A2363AA914580A490013BD768A5A0011DA1974ECA10DC190406D82BD0D6C384B00439\n"
+":405AC00092EC111E8242804920CA2F4511C801EE097311CA6EB04B11E4A4BDBC7C85C83D056A60CFA82E07C66B689E40D77C668807DE29C5E89A822FC2408EF930607B128F\n"
+":405B0000CF204315C87A6144B47725A5EC22E02A08007EA6A5100CFF1975B9426D790BC4BA0CF67D81EA6010AB3E814C507437718740786C18901B5A3218BC0B6B6E2E1DCD\n"
+":405B4000B34016746099A7A23AD64233878C27857122578809BA8E13C2DA650983B923010156666103A431A3EF22A1B718DB787C9D762D5B282D9EB68861001C8D3FFABE2C\n"
+":405B8000004CE3B26E2B6C1E32100B3C5D3C5D4B863E361516198A40274AA3004AE9041102CA1137462A2071A0129A2134DCF27D2836210F40201141ED2C9210B48B860DE5\n"
+":405BC00006598123A45D1070D10708005C0F0B81AD7EB159704D2048820347D08AB0C18036FCE1114DEEC4071C71605F0C277007DF4C420F76C428E3EB187101FCF58C996D\n"
+":405C0000F207DE3619AC8385C407836280800218865B8828D410929A52442F922A902340A4478662979C1F87985B19421068130832F41692B75CADE341E1E64F0472D1F31C\n"
+":405C4000096FC12EB8542F5C9197599908BDE5BF6939628E204D6EE30D121BA97147DBFCC375A0181E3D2010127E2298E0BB44BC92DA8065EDD4E509291858F844D3404E4B\n"
+":405C80002142EEB14410A80E0FA9C910A16853A0A32D50190FB478427ED91A2F248488884005A4077B714FB4534425E90FE4CFAF2E6C081C789F38CE843EC7D020B9748641\n"
+":405CC0002A542840336F68A82297098C18DD628565018A6AF5833890BE21C61A1C4007B961482F294C02004D354319B00A5128950CCA502C21C5F425CA192BC21EF81964C4\n"
+":405D00007B7B044D30A413F65BC0DCB68026687320010731A520086820083E1E2F2A803413DDE5C42B9E8BA91F87A8624405E682A20D212A80B7996B88A478008710025237\n"
+":405D4000895E1DD9106FD93AE36610028D10500D24A85110A15F75F2976FE48E93D44F0056EDC0910659F0D371020F7F455E89E05E981251C2DD03339F6FFD1B172D0799A2\n"
+":405D80002F840B0347E3FFD15F2218981B37D25E00E09ADE1AEE401EF268E21320DF9C2570639B1A9F7C7F89803B02C691800B0C1DF6B222012174E017F9BA244C8405C072\n"
+":405DC000840B0D010024061953A0767828FB347C4D12E91C81720FD0F1703091C69168061640D0C1DAE7846816A88185356611B3E11A244B92436250439BF58F922587B2F8\n"
+":405E0000918415D6440927DA57C43C977A6741250703AB01C8EC1C626F8425F82443F45E4890FE7443105B984C8F909D87C1FA03D041630A2092880C385BE000E1B43A0348\n"
+":405E400007A9415E0A03C19E5C025390F10A29C9CE1A812EE39E1F51500E2AD024C16222EB62D8EF840BED33E41965936409EB8621F45C08EC74E53D8627E06CD221B000C3\n"
+":405E800008C1D52B6200859D4C6E375289D5DD93C45C87A3884E116B6384B910F01C0CEC7BB26090248073E25B010340B3EAAD8B0208EA85D108C8C3D8DAF089899C40D667\n"
+":405EC000E02C8602A228AD8C7B7EA11340D254584C2EFD69130A425E10BF104C87010D11A3ACC7510032374BCE4884538081081012001E5D60403152CD88400B0182438378\n"
+":405F00005C6C6311202892038055CB5ECFC76EA45004C7580D498B4A183ED3311D0E70861101E3E462F0ADB97A0C78410CD432F2EC5084A9F374853636143D6846231814A6\n"
+":405F40001EF5ED708609007E8F99498035005014D4250F974F0C05ED4372D801C418F1C431449F4B2A10A10424875EDF2212241128218210A920AD4166BFC883143A76209A\n"
+":405F80004BA1C49A1D8481CC7AEE5812EE3963CEAC1D7488809CEBB043ECEB620502E400D3CB052069C548FB0B2FA113D03439898098CC25C223D030CAE51C2A4013062751\n"
+":405FC00001B37EB0037D951E2608E287942DD0D07C88103A865D89D83E3F2A210BC3C905E20251327DECFA6407626E10103F04BE611E2EE250100CC81D432F06FF118B2263\n"
+":4060000063A6E08E298CEC22C20A12C40033F431F05461F386843282846047D9AC83ECD683D482240F7A66F0FBE5D0AD34874DC98FB30C84D110B395CC7504747E6268F4E7\n"
+":40604000A008F2F6F1013C160E20E1DA037B5FBC41E862A420C5D8078F88486B0497629E889E07A00902BE9A411D01589B2147B28A87C34122048D51C44B061B2B42000818\n"
+":406080000989220002046915773BD1BCF83C6ED63A8401F179E8948307566A081200A0059EA400087401634153EA40011380203BB5E7C48D8F3F070D0B079FA02507D4A0B4\n"
+":4060C000A23D86BDA27C7ED9E4138086E6DE4551225317A01799CBD2D2701662497984A0417ECDEB1303C6102539001C0D82672047DDF283E66E12DC7A64072882729464D2\n"
+":4061000028BC2FA43061E11782B9A80A508FD23BA5EC8D02F340908478030CF50C7B33C110784450B8C8F805248557D90F2F6A1CA0E10231D88E0C0034826DD23449808911\n"
+":4061400012C0234FB8700B5380905DDBBC88E56210184C601A1B068181EE0912F72CA1764E894F20101E01078B9A072DC04F920C8202C0A0C702E0DC281DA186267E69903A\n"
+":406180009F9E0BF211A3D52A8206C884C2F106517ABCA087D130E3F067E88FBB909081676F7E4188956BC2ECEBE2EF568301AAC8BD63625CCF78B0D7C5DF03D49DE421EB22\n"
+":4061C0004F0402E74B0221E11F2830D9BFC7B902CFB97410DBB60BDB0CE9EC61A8B024002410E014686007A359441A083BC9010B59A1E0BAF2DDFF10A480681F79D0224110\n"
+":40620000E73309F4805BDB64246B1F44314BD794A5E99FE122820ACB80C7C776C21690DDEF903CEA5047A8810C816EF7C8448E513BF72721260A1F39370839942E40F04214\n"
+":4062400021F9ADC8460357658C1254771E4542C46035D02186B1FC5529C6034CEAED49110147B15095063BF70A444E9494101086033BDC3C8950781B8610044D0C7700A4EB\n"
+":406280000E2A10270F7BB99E13E063BE5308082868681AA6A91B5AD1D1C923EA6372023CDED9204744AF493BDEEE2881E07035AEBB3340CAEF770480E3281AD7559EE4E8DC\n"
+":4062C0004079740D70E369EE6E11ECCF323018F78B28835B6FE1F7BB80984981EB3180B08ACE0251CDE557E06B79B8EC7B216C7BB52864A5DF07C596B4240F9860C480CB9A\n"
+":4063000035400E1AA311304D62E47E0D5862FAA00C79EC3104418A06A96C4A8B21377A2DBCA255A80F604128F90281B4FA0384582607344980C903E9300A203C403C5FA0DE\n"
+":40634000F0177C0A6C3DE8B481488136D88F5116FDB130FD8126D4C601189800197C214280F207200E1800116A6F247B03900E92B80F40CEE65C47BF4D0CF622717FDE8BD6\n"
+":40638000444711C6096A7CF9AC28404EF45C2D1AB089E78017DE86285A3A28D01B6029770A1D44922C03C0576B1711F3DE8625E253A2EF42910F3D5A6C3DAEEE31E1DA28C6\n"
+":4063C000884843BD0707BD0C56047BD08D0CCD51643C8E130D3F06C58B23EA5DE87EA03D88D4481F0DE918AE680C8040440D141A2CA22741B2743DD28221ABB19008D91FDE\n"
+":40640000CB901F60643167D381821DF6B6B152602743E2741CEFB47196202BDA0446070073B5A14DFC3C50EF46831D94876640738039B00DE4D2596F79BB2E849410CBCACE\n"
+":40644000C7E230F9F5E27A70C88610285500043F43790883DEE0A749C4153F090007C4CB2662E0C81217CBC4421AA009789DB44720AE4E605F44940B03AA010B600871F57D\n"
+":40648000186919AC01A8F55B0A02021BABA2182F0031EDDA057CD3723E120F12E0E20140CB7EC76DF50F38EE43CC30B25C9D1EC6761007D5F285B56A8803E79EC2EF5344E9\n"
+":4064C000BC26787DD13C77340959DF26C87776A2C1A1A57480EA29844CEEEDA47AD5092EF5463C39320AF86BA05827E4420F410895ED5CE4424677788212C98D80BC7BD1D5\n"
+":406500005510107D4FCEEB82E0C1A5E8198163BC210BB60447B0FA8812AB622C725F8B5F523D22305DE6FC5E6E211323ACC80F493A30420865AE1021E16B919108E46B18AF\n"
+":406540009D9938860651DA4A04F0EFDA82048D0F3A9D9027D0360405DBF47BD16849A043BED7C40B2FA18BBAB98416F68EE902DCEC30C20EF4584F03F8F77F61121DE8B04A\n"
+":40658000C042B61C2FBD16C441EFB6E53CFF3E443043E33C31063C527E5DE89639548268143D724A24A6C19C80F1ED6973F60E9084195C241244990C11660E14A10C95623B\n"
+":4065C000CBF92EB309106A508025124544992D9CE4C909789608E47A8B1B7808812687A91B264C55C65B2F90813252ED0201027A43E8B603F2AB80EB97E1F6F8F10F64C7AA\n"
+":40660000B9BC0BBD1CD002C710C9212D9094049CD74A1011A13121BC3010E4E05B0800A8140888E11494427ED93F30408BDD71444584102BCAD4E6C9164EF8EF484161283D\n"
+":40664000E1203B364882088182102B2BAC8D21B336EC4062098F3E5D0909E25942E9BBC1003D9576582502B90C50EA290124085881EF34F2F2BA7913AC73B3F101025E848B\n"
+":4066800095127463D0DD91760204FE3DAC9D65821E1C511EB27E1F243F1899DB3582008430E3A28B43A1164442F57540F57730843E1B994043D41491E66C9B1E34FE12BB93\n"
+":4066C000440C5E8A44192815C101D602843ECCAD11E44F2B8403B4042E482D3E3088A0F0100A745830831E29DA1CA28206B6ED41363BC8C840443BD0C9733A8585070668B3\n"
+":406700003393FA20680A2191D2619D40EB0121048144E95CE00C7AEBB840A048EE046D600159700277AA819208F8F21CAD6507B0B24E811EBA2B28C01CC10CC922B8EC0976\n"
+":40674000D01E443EB0992ECE3C230244629EC0DA528444DCC381F58F017762E89EC23F7A7F94890F0F544F39361E874E11C78BABC818408C15183E0FC81F0D7888C6508C03\n"
+":4067800004280DCD138AD643A67A112CB8B6F09408F7A4610964633DD9947A0CE112F3C8A44BD06F0896D0965A33DC9206502381800850140B27C00EC2371033AD7547BAAA\n"
+":4067C0004147C11303DE892A13A22175DEA1C40F0243F75FD80F59D7193B4947BEB588121E81110FB7A890274622EE4444F0243E022208F3ADDD360252E510540210FBB229\n"
+":40680000CC89D2830BE98D67B131D2DDC221F44E788024C8416422ED61F1038722C82033085BDF40CC2080A3D885B650F5AB697B7BF45800BBD184C34D5431841EC2E02F08\n"
+":406840002AF7175F501F7A1495FF407EB7EF40F27003B9A9F157795772D5DA599045D5B4850C2606DDA85D8DFA5E793B4031F06CC243106287BEF80B0FB883441775BB9864\n"
+":406880004BDE7E4D0F438894071840C9C088EAC300000327038EDFBC3E2740121861DD47C4411EC2C218621C7BCF187CFED02C8828019B5911779E3A053779F922532B7BCC\n"
+":4068C00005445C44AED57430CA694BBCFC9120932197DE83A2433810CB45332299B7A1634413EF2A140D029981A81BEA9E010148BBA107A7CBC5804C260502525C8628B42A\n"
+":406900004A026076CAF8883A6C01F2E0088E0118103D54201B2030E02DDCDB04A1801189DB4538F9E5A5000805250610E7C14F84329703C76D8D8EE248376700A52531E8B0\n"
+":40694000DDDC4B0F18401E009F731F1B011F8BDCCFB6638C6AA4640C701EFB9096CDC022D826618E025F79E0B0166E3BA3108EE26A2C107DE7FC63C247F2A24FA61404FE21\n"
+":4069800079ED69412548020EE901A9A02B7C3E6C269FB07BC4EC902BEFA7110023CB348C882EF3EB3B97A049EB7B612FB6F5F1EF3EB21F910A53B4338B0408187D5721744A\n"
+":4069C0001C4901879574A006F7D8F102BDE7D688B204865536406A00310A18E7AF2207085EB70E1023C540A40E1E858191DCF9C4137A94648080C7D07E47DEF4E380240A0D\n"
+":406A0000ADD85C823E9ADC1C7801D9766303000DCD2220640C0F79E4884026DC462206C81220284F041D0DFA3D78902216CAC020C761511F40940F577E162E7030C41F13DB\n"
+":406A4000829C508E02DC5A5D70444D8E7E42772B450EF09E2207ABF24777131098800380BEEBE32094C0C19E1185E12811A063E57D92EA4641058020ABB7214825232BD443\n"
+":406A8000025107B69ECBB158CAB30BAF8D84453B89F0243B0C01EECBDC2EDEBE30AC1110FB53C8481B510103B7460F7164C9E3E1BBC1194F7214610675B4424273AEF2027C\n"
+":406AC000CDF203C38F02780AE3B194780AE071FE48886049F6586867C7CF5783D108C205893DC31E3E21571048FCC1460411C1D60782010EFB45B14C0043792F0AAA1A006D\n"
+":406B00003313BB220BD10E424178ED190EE456209858C03C594902245F6C5AC5A2910DC3820080686DB5E385A824C075997E06F62A1C214A90C0C4734044CEBC80C4028E1C\n"
+":406B40003F3F9F88095225AAA5100F9DAA10142FE821C45B2444136403C7B8225816228400881220861D73F423B8D1DBACC61CCCE660EC71C2021022079263AB05B05361DB\n"
+":406B80001B5001A8E0803A09191129B9D160600C03420343C9CAA22881604842210EC0D1E027637B02C35B7A3A3F4100BB3128431A7264182691069CA2D960704A63001564\n"
+":406BC000200F69B61A7258E500DB200C26004A5CCC5816A4020751B06D6F0CC8E0E8008684082860D2F21841FA5C7318E1490ED6211112973A3C90080163A9428F219C0918\n"
+":406C0000A2050DA5A6C7AA34C83B5F98BC2DF273208204710C307BA90C7AC4647421422290C708160BD5F057B8982C7813B47B6D304C421822A5A3EB80B10C3C6E7A4157E7\n"
+":406C4000545C8E4129005EA61A104CE9F727C9000610247501DD7A042297B1DF50F28949598875E1E260FB3BA44C1054E9EEE8D1304143A40CCD77114BBD3092900D251FC3\n"
+":406C800024728E6D088062E863D97523E858230F831D04EA7EFA4821D448E7028252FA9AC080D0FC1011075347C42582669EE6CF829A901E0BD1E43D0246EB6095C4643B0B\n"
+":406CC00067A1118C10F91D20A3085650CC051F32F08847D78DA2028121F807302062A02CA702E089CC03A3C97A0485CABDE5EE5C00A4A30C1650980805D9578A9B869BBCBA\n"
+":406D0000EED5000C31181BD73415D1E14594090820E805C7B2567B108FD0BB03DCD8820685C0D1C1D7A1626776C7F90F068FAF51C418EBBA412AD00633D6CBCD9902051C93\n"
+":406D40002101A46E76C63088434064388C71A1DC53624C0265596C00ECC5C221F8894440101CE23FEB00408008E1283B4C6C8F13B3C808440E009042C326B19E0E019EF76B\n"
+":406D80008F2EE2791F260C0820046D40A3B90C918BB8E7098C385C0A04C6D7E44391F1BA1A91C0101A462EBD8C7049C6DBD03D7728339219CE63991A5CF08E6721F0112892\n"
+":406DC000B0706C6D44D4C8221A21C08B3B2D3A910DEE4871A1C5DFD1024C0E5E3FE63F4CDB17B6674B72092E8A7C1DB26487C2C10344ACC25E22C41895A8922154615A4411\n"
+":406E0000182B2581840C40B04478007C5D8E3E2CF52363ACEA87BA1544AE2C018E7D685D05D620C83657C30E38F104468C2AA25843081090C8180040D9629277D6F0E420A9\n"
+":406E400003659428802812882001B2CD40123D6FF45EBD75106CB5F075A19750631E05B33B85809745B21D612222DDA490A364388E5E9DE9103023D391D709049F01DF11A6\n"
+":406E8000E00453B1004E042EAD112A0840BA24354602D00201F8C88044E02CC9ED18411E3B6158BC0E0E5E19391CDF7109B74299CE5E9D2C90D530D3A02CCB6034782D7629\n"
+":406EC000CF129D8BD1C9C208F7DBA9494C0659EBBD02A1E8494B01484B00081B6FF5004CAD2DBCD1B53E15301980F0DE0803E21003E65F33594389686C4B17650030120404\n"
+":406F0000B3289CA86CF204CEEFC833D064D08F892107B0EAC63C42B3DBDADD620C01F20204CCAD0F1148844D020BF20C43087D181440275C1C1176711E442D0C7BAC8284FA\n"
+":406F40001204CB4ACA1DD25E7BAD4880D3E819CEFE1870BBD03AB808443EE0AA2948F959285C743543DB04C32B034034DFA5C482A3A87571C0980180D27B0252646A4189A2\n"
+":406F8000AC7A0E84FBDF90430030132C6740028830C3E00A210988F3C3D1B143DE91222976A998D327691150B43CE9242D8CC98DA14F53858E14D0A6E0435A154EBF4C3383\n"
+":406FC000C3DAB1825990021F7B9F8D4325322268015B0A51514400924C8000EA20980B54817C6908702391604C842E783C88305A5E50863540A9354D83C01704CB22D90093\n"
+":407000009D90186B2C2705520D96F66E0D84F07B3264708595BDC6C6405B21B5E516A45C4F0068E1B2916F8FC351CF4CC5D1B9C32C439CDA0837E0F4A1367DB8F06044C6A6\n"
+":407040009430F6F6697946947D642030E05A100780A438051410BBD4F4C52A0455D48802A0009CC80855368882803ECBBF1B06F1C2A0860E97230C218320996E5B7BB14823\n"
+":40708000B7C519B043542CBBA24444370EC6F6176F11248F5FF99D04203B9CA20D094008F09490801232DF908BD6D6A25796DDDB224010265716C81D046C38F8BAA87B3448\n"
+":4070C0005062C4B80080A1D4208C4036D9E04A14BA07104613A030DB7446C1080AABEC0BC4D828CB344276405D401DA0CABECC86480160254846A000B3AF7437BF11003D2B\n"
+":40710000189D3E77111A9C2EF89D1600B1391CA7E1C50800C023DD9D12088D81875F8C09420B62AE2E0F74211FB73F4826D0A8156A8C1804DE055E1F000809177028F686FD\n"
+":40714000B902612D5A900F3AA0D0961288450129B6FA0B012080147AA010424F60FB8849291F255708175988806A0019CC808D880159C504241560881F08261F656D082F4C\n"
+":40718000EAA8B2C76C2030265A96DDD40E612904010067010C7A167EDCD832E3AFE848F61576EDF40B6BA844F613EA747B222C7B82F041C891F173D98142354310E058F748\n"
+":4071C000D8D11E04AF42C00D2C01D11D1A297602A978DAC870124101143EDC6C2D1780F42920867E43BF2A68E6F1FC219F8C1C8405096CAC758083425F520F8C6130124A9E\n"
+":407200004A9A130DB4C81EE0015891B8A0C65C05441802A2252D600C00BDD1CA33F81768030C0086F6E056B951C13A3F014A885000CF4600A7B56B8B1B9798C90E771C1D47\n"
+":4072400060C618A1228D725F6CDC1117B4A804421C4A8F010B143890613A13F181A9FC042638C162C7C05DA000FA35C08F443C0768560F204CAAF0685086A0218365021E13\n"
+":40728000013E8FB0120AF882D0ED8EDEA63E1758408043A04B86CB6800C9D9644A1842004B23FCC1F478FA34A60AF0C5C3001190C1884039032E7E14961CD9511CCF81D4BE\n"
+":4072C00088D5D51779EE889C3F6C7763E8DBB11CBC153C5810C4D3EB0371034E0083DAD4E60A1A0330D439636381CC6306C74203500C45380641FB51A8423C7902478C41C5\n"
+":40730000C6C6743DB62246CFAC2BC6E7E000EFD13328F13940DC18206979F7747528E5E4936934C55D43E9E022000F770A20607443B7A0C85F98C79A274CC2202281B6E027\n"
+":40734000E8DCA2C68008F40AFAA2A8C47180401BC521C98C2DC00D5011B27C02740123086750EB73F17A03853D4B188772E2C112468873E31DA3C032060688B8402204E0E3\n"
+":40738000F756110FE306892CC13A5A1B9268F97D58874E82681133C1C7443A7625A1F7EBB189B4E4BD158C24101A548202901A5282069DCB25D8B2446D76B9319EC47F0080\n"
+":4073C000562DA6F8646272905A621120D38D1F264D9005E079521A26F28F000CE543C9D842423611A1CEE3A6CE81D448C44001603806620DE34F96C14CC61C870BD8870700\n"
+":4074000058614D0030A418314E8997DF69E20BA0217BC2A4A287CD16E271B1E5B0A202CF78C03C06EBC28450CA5843C07288623028A10F00D276AEC499045008A89A26CA67\n"
+":407440001EB1643239D88453D5C995111078683C87740171D09003D042772568B851E0C38B1871C288881A8F58478B0359D2391E37D70B1A49E41C0E048C920D01082E820D\n"
+":40748000372820749EE20481D62F0B98828B881696B40859188BAE8F7A20650C7C61875028D082983CCB07795032910F62A80F651E8C6900DB73A8919EF51B9DCD9C8F7DA4\n"
+":4074C000DFB10EC59610DC31081477A2C539C39C86196125CF200430E8C403E62553BD1399C1E5B9A1C9A813D8C3A910BF11CE9A1990099F1E2E4E99F88ECBACC3DB514462\n"
+":407500003013050041BD122D690203C460C0C0B47A81A00C0DF8208041B113CC1C460C7547D0F7A440F7D1891C04C769FA1785074BBD5DC87E045828B7FA01DD3F870198B3\n"
+":407540007619D0901DD65E7E15731F61F89762EC10E64559FCBA656040DC4442068D74FC6A300182B4831600B086CFC58F8C06371D6290B801A98062520E9DB964B2A384E2\n"
+":4075800018033D375C20D94B7F203005E0FB1CF8E4CF33E3091094A88265296DE21CB3BB68023014E808FE00972B388078616D4CA22C86C21FBC3306CE0359020A8D78764F\n"
+":4075C000C7B061C811EB6EF11E37BD41B3810F4968C94C8DEC4A62064AD2001802CDD20FD1F843EBEB611E0B42001526020BFBCC15251000771743140B0860EADF2937405D\n"
+":4076000030549C083716E43717D1054A8083B1058880DF92E401EC4543DC5E04152C2287BBAB4582B121B15EBDDD160B84B4C222C16897AF46887067B3848BBF940B0EF0B9\n"
+":40764000410B0CE581082C80AC1C0300E0190C03901796A4204619A105F72462C3EA3E2C1410C8C5CFDB20888203C04EF11C2F382FA5EC3B21063B8254440EEEE642710312\n"
+":407680006004EE1262D869841AABA10E4F6F5CF0CF6C30A2386F13E5DEE7E36B803A819CFFC43B35C08AA065A06848283BA88C882EC012163CC18C20CE9C808E20807815D6\n"
+":4076C00058B1100043162474AA40180242BAD90DC8D4403F760B0B03682E3976EAF10947B78B08040A35EB74022471A7861412B8F00E4EF8EB1248271602F10C7B2D4271D2\n"
+":4077000067C066220A8062204E2C05DE139D2116207C7CF442353C5A9C102DBB8F1F740688174C0BC8D8A8B011000131A5C001CC16C57E2288DA0BFBBB3086D1587A0D0D01\n"
+":40774000113FBEF6480A3BA8F1057C0A8C863ADF2C766613847444B5C9A2C5F983C0BF44CA3D8431C462EB2711F80D68408002D0C6051E26DD07113FB85D058A06F2AF79A3\n"
+":407780008710E7E470B31CCF8A8944543483118812A88792059B1B2E0E51CCEA08FA2D446A1C828301442F65A85E972A8D1200782D4C0106833D51299800D16850758928D7\n"
+":4077C000EF0364091185020097AF0804121F0A070048842810068408A1160A0003C51F85E10104322F911336A1E4333A12C35080E011FB7780812F40550C28771158E9B3AB\n"
+":40780000466A2DF438C0D9B472EAC86E024BEB0B1743EE8889B99288808001A37D2AAA21C10D4308941D8EE638B34C0526F44722C302531E15EA13A00DEF5871F16599E85A\n"
+":40784000658419D21016B27C8F00C0090F700B00265262DD3F003008020F4317B1E188101E18ED3821CF682F62870803E0A1B23DBCA14441DF8397D063B685CC34F147F183\n"
+":40788000061D5BB62610F36C30143BD564BC50423CCC527D29A420817240C200E06D7A048842B25C0AF04CE976FC0900A0D01A2E03435605A112829E03463BAED08340976B\n"
+":4078C000B02004971AC73CDA020B7AEE7442D3DC0C25C2A1C7AD3144200B8F7327BD774C62DFD467432664F84E4F80DBC4A8821DCFB03E374E10208A0677D4D127CA627CCA\n"
+":40790000292F7B9E6049F0222D11D94028048482C017EFC183063C094853A082A0AD6185BF007CACB1B8103507C3DC874970391401B29CB0F70A090020A8A05002470EE885\n"
+":40794000BA5B60D0DB150F6F9290101133D391C21021EC12012C013AA5100423F1DB30976111D20458BCAEE38D0E14D6107761D082A6182596D4238827A7B023DC04C84F76\n"
+":407980002AA510041116B82420FA544841329F09F0780EB0483A0420192E256889A485056C32001F859484021CC5036810F64DC166970931A2FE127B7E10100E4E35EB017E\n"
+":4079C000982001B551E0057562F080A3D1A63D1AC350345C07BD122C221971BE321F5C1D0C900A647A03F8B86768D67097270836549600C1E445D361012A8C7C1B4920004B\n"
+":407A00000D308F81928AA9400E9A887504388858FA24A06EFC0B4D175ACA080569B793D746890169C54D55838FB41D8C1D2F461A0A7E33351F502888463A8043A924106394\n"
+":407A40005700A7D40CE241F5F9891B14A481842D2306181605C39D0E1F09DB98EE101A7DFAF45D4A94605F64200923E16B81F1A51882A3814006CC405E8A036DF86578381F\n"
+":407A80000024B815D678C222D202F78DB8B2009A01681C4B0339FD454BC620B48803E51312ECDB011A305F08257900F93EE872BAC40D1BC9320C6D89486120044E047C2772\n"
+":407AC000BDDB1164D0B361024202CD340ADE23C06104CA9B48082B54E5D4DA6268C624040132B0030A7090C060A848DB46DF63212183E82D31E9D2B1F3C4D09205C6B444E9\n"
+":407B000076F8228F2980402F3EE70FA23C074E48868E48BBBCA8B43F042597A70122790A27B01735A4740240478CA7C40829C04042B0C3305C4443C83563D6C1A402481239\n"
+":407B40003C839BE30446F0EFE0D750035E1DFF301E3523C4F4F31628895BD608B1DAAF02355134C0B01401DAA9042C0203B010813C029CE4021EC11CE62424254A04E3A671\n"
+":407B8000460D8491A611AA99E4030F3803081C124ADA2CE39100AE182F25F60F5E314E8B984048710046BE93451862EC8561107C3A1E22167DE988005FBBC808D1F7FBC180\n"
+":407BC000B1E68231280B6F419910157C415C621EBC061246CEE3E50ED320462F0EE79F9439CB61121F5AA4207A78D68480E2F8503C2D104071A0600E615101ED9941988837\n"
+":407C0000762E2613039007D0689A05D04825002007570B1469795C2C445C0622030FE207991E510300618C30DB671303842860DA2244A3EFEEE12B50ED29A1084446326A62\n"
+":407C4000C4913800B05D9EC22E11836E21222009F8120CBC6C7A24C1EC00C289EE448C05D8C2300B273F9456CFCA4625DD2FE7E9E3121040A1BFCDD5E20178C6844820700E\n"
+":407C8000070C08230862DC09C4022684C34C9AF3B39976B2D8F8C6C44DA28CBA23883183CECEE559A245F94584E99001A68125A68B2DECC48723A72FD04A81FBAB9C07A26C\n"
+":407CC0006306D7E3DFE103DFDAA670931DAB223E91C41004A22D419A480029DB46C0C028CD021656A658794B0BC950A4741E3DFBF899AE4320680F80402C0D7738C880022D\n"
+":407D0000DDEC61A0341C21E0C7467A88C4800248825D77803C00448C32C412043BF7924D51B7DD8422079220968428412F398E0825DF7BE5DA2D65E5C9123406DEFBE13013\n"
+":407D400013C15445DF7C061A7002E2023587E5B9538F71848F60C4497F97003E094123405C1DC98E8D81234061E8530100B63BB104C171807604776B933277908222849E73\n"
+":407D8000E2B63EFBEE44D016B74052222E4C9C76E1D450E22BD96864663DFB21345800B03F8823D41383D93303AC7311480A11C2027FC2C5A21077DF8A45A8351C46A8981B\n"
+":407DC0000C17D73F010A2077DF9222D428B869430447E8D802BBDC24654B8182FCA0434AFE221F00BC40042543020373FC4030E01BC3BD3888044902506200F63D724590D0\n"
+":407E000024680720800FE83DE11907818BBD330B5D9E52101E0658C024A9EA3D6CC2417FBEEE4CF4E27273A1D41243A4D7C4C0F4BF490186F061DF832861B60326A14BE072\n"
+":407E40009F53078D105FA381C889083BF04D0F6966977EDC0F7A14083BEAB4E2077E08934004EE5C11E856320C080F41B111A20E9AA0477E099922902D41CBA83F6412F308\n"
+":407E8000EA115FFC3B4C210B08E0122CCD2212F727E100054685CD07A20041888F7DEE1ECFCC225E83C044BE2990213690A0426DA038B3CA858C9C410987C674234704455D\n"
+":407EC000E23DF7DC8747439023E0954124019CB5B2B1281A27BF7E1F8F8003076A3B2F00088801DF87A88B0A1D60E8A06E51C058AC4293A2993A1977A290ED31027A115DBB\n"
+":407F00002B464C003EBF8B2340E71DBADABC7BED64BBF0650F5EE95701803318D03848860D6387BF061107521818080DFBF0444B2EFC1754AC522A18149E52222EFC1854A4\n"
+":407F40009C50268D032E6C01D48BF169F0880CF7DE3174C850D5919E04651147DC3102C07087901309835CC225C04ED74D2A1C5E79ED100BB01104401DBBF05C8C947B11CC\n"
+":407F8000344203C4ABEC0401EFC162000D62DFBF05530554BD325A2D7BD7BC582A522BD816AC0B14F602E177E0B2A2725A37C1EA8832A1E650AA77D2EC9E25977E0A21D463\n"
+":407FC0009082076BACC45E3449FDD0DC46D0009F36410EFC185BAEEC08D72576B871EA45A1D974C48D3D810EFC1A43CB09C2E5BD5A9993ED306420C0AF378A8DEE14802EC4\n"
+":40800000FC173E088E30C654A7ACC811FBA3C490602A2BCBFD87087B0454FCF648240F863150A55018141DF318979F51CA9881601CED00833590F50663E687ACBB54F913A8\n"
+":40804000CAE2C21C45AF775A97BBACC8D01D8DD636BCF11D60846B2403534074DA8F458280A0ED66F1A281BE6009022077DD52DD29AA37498303C81E5907043685DCBBEE38\n"
+":40808000ACBAF8F84D11A481183BA4C0C4A29C00063BEEAD1C4E314243BED28B5FF841821DF6ECB87CADD3FF22688A739B35100291506077DB9B966789A50ECD6644120CE6\n"
+":4080C0001534C4E27D789B70C3A095A09BBEDD1615147BEDA4C23EFB66130331C8401EFB544B0D3938075B5B69047DF6A223F03BDF6A44041653A830450CE0FF7DA9AD0828\n"
+":4081000001990D9F703842400303CBD2908209F714413C4DC0201109805D977C7D148E20D67B5081C4F56B804DA4541034FA0633DF0CD009BB2178BE0BAD1253DB9783DFCA\n"
+":408140006B0981A6D4790EFDDFF87D668621369CA87BECD0C0D30818D6BD1B1AED41F821E44E0F818211F1D3E9F602321C2970B853110965EA3DEB4858118B8531168BF92F\n"
+":408180002098546426B8D0582011EFBD4212F6CAE912FC191C5B1F40897ED3362822D0A308965633DF3D4801A0D4E85EFDDC3EEDCC203A1CBDF7203DF69C808187E0B5ED6C\n"
+":4081C000C59F0C877DAB24031BE18285F902450619BE2B5DD023A851BF51882E0BF7D628E3D913012EC98012C72E58AF06031F5C58352420303F71B8F4DFB91006B77BD1F8\n"
+":408200000D8900961EBBDEA440238FBEB187B6B74EE9E02FC85100880800AEFABE305D40F604BC344E25D77D5E265027BC11880639051BC790F85628B0FF03001997EC596C\n"
+":4082400049EFABD1988C14340AE4FA26A0482742C122A7BEACD369837CE12049E148F639085F38D59F80EFC82510821127C1F853DF4BA3BCF697682D0802719C26E0E3348A\n"
+":4082800091B839C191E40379C85487106F14B01E0039B5907E4400E00D8E21D9A44AFAE358416C83A120346B020179DA88822F20C82000174140363D14041747EC88F6504C\n"
+":4082C0001040DE178020816F3DB78E5070E02E106CF62C143284048434886DC1A8780400851A86D125B0350F7CF9A607E8E10767482207BEA207D99EE3D97683DE38420691\n"
+":40830000F5F7B0FBAEF4409080D0F0D9688F190A824D602A312C710AC7202FAD4110C08C888BB2010831ED4F140302640D3E830EE2491BDC846D0A4400D003BFBCC4BF2288\n"
+":408340007708D43B77B5A1EF3DA202F7B340F42F30B0708263814040D3A0EF66A361B370758331DD33D3B684C890C90B1F2B2F0B1D9D5623C0D81175D8B8EC3133E75071D1\n"
+":40838000F631C0EF2A43DDFBE2269B25B81E290327017245F990F503637A072C4163E57CE1C13A003FB5DF08A0DEC147D4F2C406FC0B0640A84048EDEA824116C0CED81AE9\n"
+":4083C00037E180467882A7514E7404F5B246887BA4112F43ED8C3009EC6059060D310089CF72900CE3DBC0CBBE934BBF6C0BBEB854B6F89C0781B8DC61F7D70247A554070C\n"
+":408400007D7088380B2241D8E0B39284C338A8099E40977BED8F49898CE481A214DCBC03C8A68F7D1C17960BC4E0607340B6EFAD8106E58E8229762210B7E98241183B1EFC\n"
+":40844000307BE904FD41DE27030391E04D56F262BA91065C23C773C2C4BD112C16EFAC944D203ECE812E0F05FD1DFD4380091F01E7175DA4884C5433904858041067005050\n"
+":40848000EEC90613168D1588DB98079F00550D4D8746BC080753A5BD43977CFA8820087A98547AE4E08BA120A8A9B2DFF88800841113B0EF8423A9B4BA4980BBEBA0446489\n"
+":4084C000E18D91015045EC63D30DB5F988519443B43BEB9D1E015A3D93223DB2A73E5DC512AF46833B4DA14E276E60DA18C7920C88084B0F4719C0790147512329100A7C37\n"
+":40850000110CBA1234F30261F43C48FAF9EC8009E111C5002220CFF521C2DC859B262D0E5D7B5456E5105AEFB12D818D40E18CB71A24050548FA81D0BA6330414053BE78A9\n"
+":4085400092F03009B1E19BD1DF26C6FDB3DE194401F4BC4169F3C7BE78C813520353454BB81E4BC1EA85DF3C640B9B63B02D145E17BA2F496A91C000F869008D035BBE7880\n"
+":408580004AD1E5DF3C65D6BA62028E43577CF0A18A0430BA88D5DF3C2862321060173398057B9A10451348CDF356D21D822E2010F207F7CECAF3AC0065D0906998CE7582B3\n"
+":4085C0000E401258FF00A2F2FAE8F62D04F8C4FC400EF7A02B9942CFE21177CEE18543EA402100829FE0DB71103BE51CA403D28F645A900304A00F0263C3414209ED3A0207\n"
+":408600000BF702F0923D83766C903D78145DCE063DF320983EC7A69B4474EC5951182C9E879F330ACA038354052F0E9889A32B4878089580565D7B5235B212C3698191401E\n"
+":40864000613C036340973449734898C9832C1D457CA81242068A6CFC34D244177CF30803DB680581B2031D03088103BC2877CF59028A13B10E5A3CE18923D8DDDCB548F27D\n"
+":4086800000C1FF5A70909B88D86810904C77E4A25BB4794EC238D4117C17A26150FF50880472B3011403F45DBA03002E0077DFE258074A542387849AC46DE889D1EF9DE386\n"
+":4086C000EC5BD23406AA9609F4B0241953D19A84680C9A2E12E6C6D3E1084440F37830EDB3843CBEB83DF3C26310EC0A2880A472CD517FB11FCBB12247BE7807C2C8A41129\n"
+":40870000F7CEF1F6A780B0CB3EF4972ED4F642E300CF011EF9DE3DDB10411EF9DF183004181B132D0805104CCA71D4752AE0357011E21E5F48B0374BD66E050731E4A38212\n"
+":408740002AED8C45B01ADC94551C1DF3BEC8FA6885E44F8F7B8860703CCD30B381091027D2A22877CDEA7DF376A8CA688446904532A4698449F7CEA35DF08873089E2739BC\n"
+":40878000A20C4DC20B291D5DF36C888AA420E04043BE838F22791C09478110BDAEB044E680D10F032A25DF4209696A8C8446E7A2C0BC413411179DF3B8882EA409F9872017\n"
+":4087C000891157D67D0454EF6CE5A2532A0A06DCDF12043BE77CB49365E3E7F32430A90F7CF10FC161D2C14400280E479172A3447604DC9BFDF3C226FFBE8D88D8CDE2305C\n"
+":40880000FF62003323C1F3A44C09A3D059DF3CE4778084C08FDF3B0221A0741604243088C908483A98775650B1DB36E2E024A422A0EE2C104C097BB81930256EDF64C099B8\n"
+":408840008000981387A0B3BE78510B0D22CBBE788882101E80F5428808134014027EE7E31EF9A8321D82F0F6D8AB4CF200A9D05F1E25C5A24AF5E43D909A65077CD5B5D874\n"
+":408880000B441C80A3FF727B49E03F0102480228827DF39A9F987A4402EF9CF438022894D3215ECE83811CBEC2E23016B502E5E79AC2EF9CD5C4EDAD7899F3CDBA0D1EA886\n"
+":4088C00090660360F9574C8306B8E97A90023DF398982E610229827BED60B1DF39681A43884695FC41DBFDC2C895B174162A4063BE72C6E62004402CB273EF9CB30854C0D1\n"
+":40890000CEF9B44B46A25DF36A89CFE31293EDC11134460C51A84812EEECA2380A13D08625B1A211046B8B44F8404F024380607A0FC47FAEE9C4F21E8D015E9D0FB20B0B26\n"
+":40894000DE94C3DB3843E89F41E96BB205F548226876CED087609FA8130432A8510571459793058BC2D045A1FB2C8A82203A2B80FADDD06A36047C84E10D0D30EFDC23A223\n"
+":4089800029027A2EA4023F57151F0B231AB723403FBCA8320B442A1CCAA478188986D29100C92070173107005EFB43112F0C0648F502BC002481E278F2C042178F001012EC\n"
+":4089C000E07D0BAD8B1B094C65DF5A2A7044A2AEE1030620E230AB8128B3183D91825AC622014401FFBF418CD006EA31106947BE8919D0B40EC9B222077D11AA03AFA0220A\n"
+":408A000040869C0BC860582EF9B04788601E05026060472138B21D0B126160702003D98008F10AE2098342B41EEFA4030CC04206EB11642B489F6C078101915A9A04256F72\n"
+":408A4000743D1F008B9081BEFA3E42524C1DEA076A40EF84CE04D00236AB31C7BD004C21162051A1D1D03258817064008327F95E58818CF7CF8103DE9A9E5FAC590B72AFE4\n"
+":408A800011D512E0E3414C791B5D8AC27E2F86264111FC13DA06C80911818DB5A47A523C7C5F0A573E40E5BBE6082404865145AB7511AFCA5CC5BFE6962DC1F81F5040809F\n"
+":408AC00038182811F1B79A00799C0C0C08D6C86F3745B0D20E1BF1DBDE08762A74D0C3C192842F243C5E924680B9D3F4C3F0A480EFFF23D6CFE2C7C1A4C44B4AC8D1163C6E\n"
+":408B0000233EA4D600796D212EF5BB39381549FBACF0B84F00905293199404B6C5481E433026B3914423358471B4F21F8B51C0AAF20C598740C6B8C0C7720FE0038122A2BC\n"
+":408B40004C264CA700CD70F887EB9AE400A3443D1E4B5285021F23C8CD10EE180E5D29D881A5F920697A721C98DBE7084E95178BCA88D50D09DF179D101E608020782D1260\n"
+":408B8000813A00983B5DB90200780D1084A8C03EDC4B2038F26F18504A40C10100E39A18C3A93880A0753F3AB91004D20887DF805A87C25F82698FE798F25A8FC5AE3F5808\n"
+":408BC0002C8202C8C22C8E13481DDEE9C40E2CB570231C0698363C02698F05A966101666096601779FACFA4F527C5E7081A00AEA52C80E2702520760DE436B762F47A425BF\n"
+":408C0000B5BF1048C78C0096D02F09388F0880209034F479B29AAAE2DAE294642E2D30080994179809F7C48223D70BF62EF80023C006D0D38F7BFD99C2601EC5E1DDB89FBF\n"
+":408C40008E4C50FA5AF87C3A7C27E900298422778FCA8449C3CC0C09DE23DE1F8536C6B1440DD0DE8E87B0405CD3D10C364071F053091499DFA4C1EC5A73AFA1DE56462C19\n"
+":408C8000BE02D33F34E9980E5285EA18148C520BFD36DE40D616B118C75120D03B0093F819DCD04401223D43005DFA7C208FB39D0878042840F822F040D15818E2244668CC\n"
+":408CC0009CBAA5A1108BA143DC6366281E002F82D70BC5A4421F015B00C0F741A970F2D29526112603892179C08EF7701E952A33382FEBC575786370975A7C911EB7D41471\n"
+":408D00002A000F6118D133BDE44E86A270A2D0E962D1127A7A807CCF4E3DDB7820357BA03B953B6B60F7968897A4B7C2BDE274E19C1F816C4598B0C8AE1230A463BBCF46F2\n"
+":408D40009F008A071CA4F9A03A884789E068178486459897A0676FA6098D67244B694978C740C22E957E5487A8C500E0591C83A503D948158398D66895811904048106A981\n"
+":408D800057A04C2217409A214754A48903D781623979BE947BCD44BB16907578446067FB8835E1FC01244D028C779501472C0F0C1B110BC378440A9408E474903D752E3E3C\n"
+":408DC00032001033DF3EE7DEC0E384283760D106C6E2C87518EF18825BD617A6059DC0C6C0B865C9296BD10411D359902A3C12D4AC74D32803E3C9200C03A3C410532005B3\n"
+":408E0000022284413D8A304C762DA58816CB3A1F22F1095174AE4155F8321009B2D0253B354C628412F193308290420B1A487740B889C4D0419F9046B8F84D1424F813B191\n"
+":408E40007A8887C2AD8872000781B3BB38501E40E03839040322CBD07933B6AC08E83C0584F85FB6BE178108101E00E27C2BE14FA3A1871347E15FF1204A0EF8FA538591D1\n"
+":408E8000101C65F7C89102891A2345F8224C13E0593210050028601F789E986FD801CCBE1600CB49C6E35E3A09D1062FA72F107B97883D8808187CC0E422F133BD808F7D16\n"
+":408EC000A911320617498321081213779B19102386376000AB8CBBED412028BEB8F4D90AD3028B2872731E41404C74A8E1DB42C40A269B9D4C48F0F3D0941E7CC02AC3005F\n"
+":408F00001C0CBE442B3000702323BC6480026E81025002639F8788440B2E42C1C8AA8F28C00547929803EF960304C1042A5444DEA1B81F73D50840290EBDECF45EA5FE2C24\n"
+":408F400064D05C0FA07762C10FA05B4FD18D84010BC06EB47481A3C01B0504028441F80DF044305042284401E4A2EC2EB23CB81E61006680279C8C37C00806250EA014E678\n"
+":408F800001BFB9FAC433110131C4B7137BE5F08144FC2A4C24F81DE69762EEF2F1024D107B38E0412060A0EF97A40D707122049F0469501E01A65FD100A747BCA71183102F\n"
+":408FC000748ABE08468B90042847BEBF8F6296100386570819B43316F4482C0288839E202E38C132BBEC590E3C8A4131D8CF7C191771481033EE1621E35A45B8E516EAD88A\n"
+":4090000085BD8403D58220300F05B823E185040081B401142A1C443F1720977DE3A11C16131D225883C126A254BBE6EC4110410D2D81331256391000762C4B8098B8337B20\n"
+":4090400045A44813C808EF9BB4BD5AAE25583DE62D81ECC2E43D856E850903D006B34949C4CE344042C413BF3CCC10BF5FDC8821BC00110417980681AC401C03B97413F83A\n"
+":4090800070506C324128B0129ADE1C1313610053B21B45925CE321023F038E9055BE2016D23E2268004A1A26613220F7AA69639000283DDBAB84CA208C03B80E264A2F22C7\n"
+":4090C000C08B1A0012D50E89044C846CED6823C38204EE238D030FC3870448003EB454A343C3864640642C15D4A04704F1F1D87203ED64F22E0E5D62C0979DA05887870779\n"
+":40910000C581D0E9CE2612001B018D12E0ACF3E1B8D0102E085F29240F87108FD7EF2527000FB337473E78BD7EEC4391D3DEA66411786BE87C796C470F978744F62D8E32CA\n"
+":4091400010F22FCE3214F534BD232081CC417B915C40A09CF408C81F0D5809280615E10786DDC8221B90EEC562E2360368B8B278086301F18828365DB9104621E8B0108128\n"
+":40918000021001F1C26083042302211A0304DE1BB91ED0E010180A1AAA6C21C0E9213A71D098F0DBCA009A911BC1E34491024B57007C6E0D90EE012905CA105C40184F92B0\n"
+":4091C00067DF7D6375F002242708D61C9D5186006795110CD2A82CA1E1B173666C2DF9F4667123416F191C8F71AF8F86D184B74624C1B0303D28022F3C7B8925471E511E4F\n"
+":40920000862623D044A2108DF0DA5095A05418012594E41E1B4A3A388010A1E1B76263509234680B94E7B09E40700C806370FF33015F0DBB24344E46004DC40BF86DCD1625\n"
+":40924000E91888338322929D23361B3C4D8083C399280049004A00940128025004A00940177C0D2264B3A21C21B456403B1881A41F5E50CF9C1800420080268FE4888F0F00\n"
+":40928000928F83D106AA0881A6E2C6BF8C443AAA2D7F08880310F4588855583554891C9F8B47C4AE0180830992392EA96122B9C3C38987558427381669F870C0C4E488329C\n"
+":4092C00081750803DA0084E8620D6E3D39362F28842C27523C4D9F0DEE11B3E1BC61F0DE297875288F00F70DB18F88F6C494F76461F87840BC3C385E1E0E4B0DA1096407F1\n"
+":40930000926D140DC84F0E08A241219FDA3E8BF51B9382F0B1E90542E99A6209FB99084200C830DB4F46751207A6948415E08EC582983C3B424C5DF81C3D2C8053867F21EA\n"
+":409340000BC30E857E886D998220201780028FA8C4048D48000B44124BCA31227901436EDEE686C9EA20793417B19A1A2367B22548D0010B0B23C17A17ED958613770F5120\n"
+":40938000ECC1043416E348EFEEA1612ECD41EC7B154231C003F3F6A88146505FE705C1E95FC9203BD5B8A0C3A4D01E503C5980C56C98C4252E934078E6530188193182CA30\n"
+":4093C0005D2680F1B6A6030AB262034EA52E934078D053BEA224C65F29749A03C62A980A7EC98C924BA4D01E4CBA66029A32631994BA4D01E2BD4C052964C61D29749A03C7\n"
+":40940000C522980A3CC98C0E52E93407899530144D9316F20C2080182305FD38C438ACC4EBE93482E93212010BFE933B48D0030D1F6E940C187193F103120338C9B0FA6C97\n"
+":409440004C6087A552C58051205540B61C843A4CD07007C1F1B35218020D7177E106B91F60835EEE0C106B8DDB08346A7040A1D6098837C5E7041B160D13DBAFA590DE4C32\n"
+":4094800084F640023A095F34AE0820689E9EB1D610D40A1E81808378C23C7ED05D6690178B92066E102C3E3F04F3C4FC3C4FCDDDD8BD862A3AE5B1EACB858D13B20D13B5AF\n"
+":4094C00023B591DCA3B991DEA3BD91E0A3C1975A158B0C367899DBDE119B417E74A09AA6892A00E3031147DCE122101C2861821289124422360112E4A2F7ED309CDED0A6DE\n"
+":409500001F4BAF89A473901EE105239F0AE811219F8C5FC45E0545A047C36202049951E473100051207E084019F368A2344DF8B02442C004B18C2A3C26EE76699B9E1C8C88\n"
+":4095400012E480004810D40923A9B226C81667289E245627432C490EC66B2141034788961E370032B8BEF89A270081D54FC24123ED56911BE8381E23B6E7E05390701F71FE\n"
+":40958000CDAF20076264104C9132091108910109129811052F68035CA004418004053B80425C6D02C170041EA4822212203122542065458808088380080BE5CA62F71D90D9\n"
+":4095C00085E1080FE71292E1FF624384B0C0239E406F8C76CC4547D11203803C0042F4481D4DA1F8042F848C14401305E1188E13F68F48C625166097A3554408F86460BC33\n"
+":40960000EF8043CF7AF808040B8FA578FC67E0C8083096099E3B1F413786894EE7E0F33DA104E655EBC1E1191205481F1B39102A6081DE64761EF276105819080D9350970D\n"
+":4096400003BB186C4022DC0E0BFB2FFD1020A60638026A0E0040CD5284381B5C2D78BC243E4041151EB88C990E520E07D1DA05794AE87C354A71A54A20F0F82FF8FAB16849\n"
+":409680004CAE9DA8314818E22A67180748100703638490F407220285BD7C5260406D3520680F3E56AC1EAC623D90BC4B2B9D05825C4C06C7808FDAA2C33481D442F03C021C\n"
+":4096C000243D305E3084080F800B1B22389AFD468646CFC1C1827B00F0C7E8C392F2EE188140DFA0E14C088A2033D8EB8201842C0086C815C2C98BDBE5C5E97B92F26AC86D\n"
+":4097000080DB65525DA070401945D46F28008007BD080C45ED1481104A30176A032EA35F2DCE24B6A0A10461D01E7DFB98200DB80C090182FF278509AC2279D3F471798121\n"
+":4097400083D5BC0219A25D00DDAFA63E9F583EE0381E11A04C1A022EC3E47D7D165DDC943E3CF8128485B3009A5E2F6419406872C61883F500E9807AC01A601DB0269737E3\n"
+":409780001751AD17A938461D4235B24452028EBD1AE08C40000385B098DEAF840D0C32BC1029FC9AA2210190CF512D0803D44A82D802129A8A000E7AE1340084E5C280020A\n"
+":4097C000149F9B5DB180215938CF6DA09056503210F061A10B0646AE1E1073AB37108C0311C220090DEBC89907418DEBD0B65D013D11EA2A03F703316D1D4206F5A12170EC\n"
+":40980000E3C2E33B420E4F820E1E10C1C60C47AB2F8B8205204CF514134488A8050477F281222B015D28712488B00502E028027780A4889DB22E09027401248861D906A5F1\n"
+":40984000DCAA03DAB706039B2178C00F0BC12185E9962402FF06A517C2A233EE5C2400A2B0FF30896F21231127EA45B1148D13D76DEE10E6B0C492E27A02079A279E77589B\n"
+":40988000885ED096108CFF040960498297AA268B13B812A7712BBEF30F9F17C8F4F5CCD892A1A6E0E820D82BE060D9380020202E0BFB74E46AE4095058950CA2CC745005F4\n"
+":4098C00097D748A4589C4589C05880658F19B9307852F3B0709B9B76C204B0217F1083DDA7985D58AC20A1E1A5991EB99C109BDC5C645C81DDA4B83CBCEC4D034B229C80A2\n"
+":40990000D2E0FCEED6D101822258313A41D35CCFCA641147C2FBC44A8044A846068440BEDCAA40D75F1F95B4C01738325ED0BCB82150C94C2030CE05CE047D3CEA207F07A7\n"
+":4099400087205BC08E02C1106817E06E39B1F40B79547875C7F89C217F58B9202705FD582E90F47B7C383420EF5C86892BD4C008807B6E94B056FB14C06CA0058FA98408AA\n"
+":40998000D8F349F118074752180F56130882A04094C81E06229801E257238FB0E38462484364112803257DF6AE3ED3E8304C17207C0B463ED3E9125414CA9A3840057A8612\n"
+":4099C000E4B7DD41ED0769EA1CE106A8D13066163E666D3C88211819E292E44A86C38793DFCB3284844ECC7D43D24667C39E07E100216B872A8CA50279503763D5DE220DD8\n"
+":409A00000366B4AC386DD8831C0C40B1AD87058A1017D71903C3B18F818A137D56C841C020680F7D586E8F0D641EBD7B5440510F40334074CB491EA1E7443B44E05756193C\n"
+":409A4000A1E4E5A2F3EA5092A1C92A2C784A80BA8774AEDE004448DC5428150801142EE00084C80BBC60502698CBC01F4813F4BA518F609FC03883DD4D6201989E1A672DB5\n"
+":409A8000C04045FC524577E08903D829D4344379680C4317B5994420222EBA8CEAA1CDAE124066D334083DEF4691BC1C982E8618E2EB1D2163BB680820F3FEE8FA6C746533\n"
+":409AC000C3D78C83DCD667E78BE104C18C38B002027E616C302C70B11900431469030140084245A22E28144C02C0104464223038985AF626148304C0308B883D8833EF872A\n"
+":409B00000300E9F90F7C0E34BDE8CE4640E00954D1556A9EBB981EBE1B72B012E1F0C2C393BF50F08843C0FA0BA87896ABF3EA1E34011B1E179929C401254501E0271ABD68\n"
+":409B400035FA3E99E1105BA877C4102A72EC48C1F853808BABB2C0272E8C0F60E01F087E1014F4DC1010DF5A0B83130803B9EA1701184BA89D16E747761175049301C0F4DF\n"
+":409B80003D00F81540A8103A88748952EB74653EAD6020F82F50A8021C3BE7C64741341B3AB84CE09D150A67627478A9829C2B50692223FF5123182DEA53130504D2C0AE57\n"
+":409BC000AAB40093613004E2EA2402F2A11A173AC1620847225E26010456B7302943AB7750108A6101C230811B5A9846E5E80F213C3BE3984A6F739B9121E2BA01088A6EF0\n"
+":409C0000F61C44022AC2FCFDE4896B7AA06A96E4A877C599503A432EC5F71EAE0712540EE9FC722543CF6DCF8F563E99A05793033131E91E812541D18078E9F5530389D0DD\n"
+":409C40007A0C44D1E06CEFDAF22543FEAE4F21CBA7DA0E0848D340A5F10EE180DE9B831000B00F3AAAFCAE5F2020F84EF9D0F736991200E0160105E3012A1710DE1D792F49\n"
+":409C80001EFB09A04D01780707CF18424CF526AA1ED2DB40021842FF5E95286105FA2684FB8534BD78AE3829880F1CC7A8510589717BA808CAF890E9BCB23548A25447F65B\n"
+":409CC000F048831DFA1E20A84FB50209D41A0142BD2A00287E9983A820888D0F6998827EC45F3237842C912FEC1F81E33E847876DA511A24B835C01007870A895A0EEE7AA4\n"
+":409D00008346C4B7F8121C4081028E19C5D40985D55905D40925E6D7111BA4062F241031056B54CD8CE531E211A5D322A219A554E0488203006000E8E34B3A088713AB2589\n"
+":409D4000C47026107D33955910E217C724787AD79675A563043216B68762F07C11607D0BB5C030E1F7C44766CE1012555290A76584703A9D5C7CFB6C2C058805BEB9DE403D\n"
+":409D800000366A714022F781E14B222292DE63EE1F0884088DA3A6225B00F09D257E2361048D710C09BC04020F1FBB97791D8DD131B07D881443E1090C47627493FB35A9C4\n"
+":409DC000F912F07D5AEC2049E7EAB072378AD24021024E78522F8EF40E203CDF240D2F015E087568213A6020B63D21842E4FA83F441325854ED2DC11307540F000C7D10843\n"
+":409E000021F22A020007AB58CC08F26C411DA7B13C0481BEE31D12D8A9D78C981FDB35C60A96230752720F630A8E28B8F620F89DE3C0218EE04922581402835ED6922F2227\n"
+":409E4000A890400981E0F4607B7CE4F0DA8067D9C264C02A68F9621D1C3D8009FC2868879621071A4C12C051D19C3E3D524C63DE06E40072111DA828EE021018534788457B\n"
+":409E800016E04C4068E08EE050580E8780E11E038200800F316F98100C77BFBA144C012EF227324220B1D3C05EC55506EDEC5CA86298E3AA467F9E1BA3F896878313545381\n"
+":409EC000F0C4261C6038C360BECCA034F4DCF260C2000779130FB4C4480E040CE6043043DEB6024B0823DF745C8982545A98350CE24693DE0300125BCC50679DA861A71656\n"
+":409F00007C33D3C9EE244B00DD326E56291B1D81A9C766C461DBFD8B56C06705D70580D03E06BF4000090E809656B1E1EF9FF3BBE23DB31032047BF8CC6818CB4CD1F0F87D\n"
+":409F4000B89C649885EC47E1F67C30FB014448D03F1B60041378803E69FF2DE5644CFF58C3A4031AE17FAB4D161582F5528FD0F0E3C3A10812EC8624377C222445E257D217\n"
+":409F800063258586058CFA31C4D600D13A218C02C7185D2257CEF2C447F6F2989A64AF953F480EF3262094969C23A007ECD551A1045A48CBBA230B721E1303D5E3661AE58F\n"
+":409FC000C61027E667C1B8F80E9F0D0C08CC1F7C1D662027ADA68B934D962440DA53C6B9847F3C3D216A5B4830EC6983E45B521FC462544B8A03A813D2FC8805E6A0A1232F\n"
+":40A00000CE901C603E25C5D40082428FCC4EC89323D7ADD504721A88D074E8F49D99611A0368910789D08C080640328BCFCA25D62B42618C177A46FB5236FE0AD50B92C4A4\n"
+":40A04000C2DB17CA204034806180581E810254E51C87A9401AC21677A94C04588344752F1B5C41F7E39E0100C6225406CA9A1F19BF8F82F9CAE3420606400CC4901808985F\n"
+":40A080000C311E00D459880A2059D8B01022401D2C303D2DAF3475CE220375F4D0F6B11882232418545A62AA770290EFD43B05EF220440507EB412E06CC218698B07A91D76\n"
+":40A0C0004488073D283A2265581FC417E240F6BEC911C881E111F9E959A1EA18C2030A6AE343AE04CBC987693035750A61712831037CF6AE373009BC0063E683440A972583\n"
+":40A10000B9F88E71E9E102004C82BA88000F803611F26D9584CC60360E0FB4418750A72E022FB0062389C81652EB202360790BF6F4E500EEC6B0122D003FAAB14C0E4BB7E8\n"
+":40A140003F4B01DC5E081EC2261EAD3B100F20E87E157B1700240C11819E01F87F069015BD10E02987D96608E2684370EE32D49001CD22D7787C12D76F3C2354B5E059E47A\n"
+":40A180005194069968596DE8038B7C0AA080AA004AA198D22C482E22A83D8F924019EA17F5AAB203505F79A09AA567643B2039874A42531F840304A06FCF93060E1AC4F68B\n"
+":40A1C00035A0F6EA749403D81E42EF2B43D8FDC5E375316085F85F8C48EEB3D2123BB21FD2268700A9302442A42892F86361C4031667A46F8A060D622FB220103DC18F0A70\n"
+":40A20000242E0883A1D88E298C5D90FEA012A86B301E99012D0D06037207C683E3F6462373A0ABECAE347B21F9A737B737F44AD60151A02C1B5D9B8C2C004A35127D90FE20\n"
+":40A24000F24040455228B0050C4E2C014BA0107217F4E86118D726ABD90FCA09ABEA0DE810B039890A3D518C7D90FEB81E5302E3028060049D53EA22301444B412AF06CC3B\n"
+":40A280008266842320B5414BF7409BF7C023300435B4B21C0AD900349A47B21F84010BBB2A111E05B841178339900042D4BB21F98EAD5C2B52095008F7D7E89AA53D9AC35A\n"
+":40A2C00077D813BCBA0A8720E8AD10706C07C40B0469149DE5145C90008B5C8961047C493E34AC02E10AEF280449A43E16BE108C871E4C2DC50C4360244A0BFC9FA6367D21\n"
+":40A300000BA200D6268BAC49E00790C7071A15208BD2CCC3550855C87A4BF048421B161810F5640398D556694401B452226D982D0C03688C50509EA98947D21743360536E4\n"
+":40A340000D7DE19DC17280E20D1AA41FB4F326BB07CB57A255DB011DF8887BEE6C4D1ED22B104742FA267A202092050F80C153ECDFD235C7105C5CF0DF70F15271E234637E\n"
+":40A38000EE015109801B14405FE7E391398AD0838CBC8EC7DA47B198731A1A25423D888EF3CC2EE22F40E000B898E99C8855E8F0941120BC5D645E6CAE2F542C8F7B460FBD\n"
+":40A3C0000FB01A68031EBE3081EF87A08761FB2040613405C4005EFBF023D2CC03D94E8566A0648961AB35A3E77E82F208E086A068B5626445403C9E4343BA7C0F8511AC0F\n"
+":40A400002EE3070902C171806A88A46805E67153042F4116435440819E6C8F73BA0D9DCFDB35A20F1A01F9E013DE8620113A0111A131FE5C1E0129A01E1B5E2B7D9EC9E036\n"
+":40A440004356E04688776A35EC322E374C450047007003CE385C82C6416821F7577180E0285DB696181C4550210910088E90FBCB1A046B055D9902225AD9A00FCAC41F36F1\n"
+":40A480008F4D602880369D5402482066060DCC819038AE9DD105FBC2E06FB10EE227120083F329E0805A5C02F01C98DA700090851304B60D4AD01BB7FAC8FF2FFC586C3D25\n"
+":40A4C00096922030CA1721C19610B360F89499060313615F06809108D9B8831152CD8A139E7D641ECB601225708634886510CB2A406363D5726254EE768812562F4C8054A6\n"
+":40A500002A9D0F6D66B86C091A501DD886CD00F1382E381C196C8877874383A1C0C4E85F0944F04D0688AA5D91E40765D19913E70961F505288DF62E600A3F94C0D109AD86\n"
+":40A54000E26017683193030BAAEC1112C5CF2C07CD8B957939E459BA41067CB8AC21D3FA2050FCCC0C309E80854B10302E5046A0F10503211DE03CAEE4FD1BB2D49EC2C56F\n"
+":40A58000A443681945BE970D19D500680C15AC58F2FB0301880806B2BA608AA510D0346362A32C382B1296341004332C2C5C965F709DD62D13B970EA41D6A3AD895203D865\n"
+":40A5C000B03AE4D0AFED31AA8B2273EC24C4DF9457910782EF3EE51FBA720B443027001BA3461364230200DEDDAE1377545A30C01201A80300920DA46851858094BD00F832\n"
+":40A60000D6209A3DBB922239AC679B4761AA6B1B651E02B0C05485804AA743BB3547A45B66282C140C5AF00A18C4B01E89E488E625442781A00DC64DB146FB648023D6B262\n"
+":40A6400090C7F40CF66710982BE9022F803344B1BBC008919FD33C02029A05B5CE2F1A256F667220040F4E4558145D288044A85C8F28B714181AC5011C111C2449EE0E78D1\n"
+":40A68000B0411EE26430140A058221004C160671C086CDF32368193FCBA3C034344A0C0D0A92C91B0C89A6C4828D26449A88C6048BF410AC0C67E8215D17AC87F745BB213A\n"
+":40A6C000E943C3C2BD90DFD99CCB380CEBE903C524668F2030812495989102BCF628381A14185300469A9E2020F647714E31408EEB1E4338480C570079170C0A1E19EB1123\n"
+":40A700005895156DB4181B18D631889330089B6A0236C04C27A9300395C87983404388B105CB902BAFCFC6D482528160719540D10FD003991185D1C0791144F606D707E453\n"
+":40A74000CB5487292B985C3C181A443147B4A447038977E518E05C508EC0DA8F6783A452A552021DEAEAC8171A01100C7AF535C955080DE39021AEAA2F473C90E43877F671\n"
+":40A780000179DB3848C0958DA02C7BFA147D4D2E5E76E522B807F4CA010E3E7B1B39A83C2AA2240D7808FC5C183E42D843C1750416083ED07720A4021C0019EC0D00506133\n"
+":40A7C000167AFBF91B58C30088847F8C5E576842DEC6592886E3431B78105D98D821B6F0283DFC5F382593C124B08C2860B402D540073342E28178880CE5354E6020C6B9AB\n"
+":40A800008409509C9501CD1392E076CE1348E148E16DC16F85BC000357081BAD670C980E4C85DDBAEC80250816C2035BB52B4477F5B6C88E60D797030AD846516F7E46118C\n"
+":40A840004B0BBFF284D1023E1B1E22A4D631F7BFF100CD733C7B1BFD551646D0075E65C986121ECAF21CA06004B20AA607BE3510030DE9F912F80F08944063F5881C4F2418\n"
+":40A88000D62CED9C5E330C1EA3C44AD9E80120B5EDF0280BC370F448D9748D02D0F0220D12D3B3AD552A5234966815FDA238256A8016C0A25196B340AAB680946913CC0A65\n"
+":40A8C00047E825D817EE08459A04DDB4449720903549AB6318156D244B54F37F844D34890B6981AA4A47236D440AE4E3843FE12D836D5022170A65E0100E0AA823FE23E3D2\n"
+":40A90000005540E3DAE5E03408434474B6CBC88164F321B80D38AA810B8180F133501DADB4AFC29746680ED81DC017100052C42EF0EAF2217281AA2D91B6DE50A4405B1DF5\n"
+":40A9400081135867C494233ADDFBE1BB8088205AF8F0C4ABB070C408008EB0510D56091B40244A1D9DA498A16E953C6CBA582F400A3EA89A22281A1D289E0366C46B20F690\n"
+":40A98000256745E520FD98101BDBA47699C160DC5D235D625622B590E97DFB72B5FBF6211B39E801D6C54C4FCA0081CDB290DCCF0ADC42785BD112E9443B091C872645FE0D\n"
+":40A9C000087C10D8793F83D65CC2CE12E160134407059203F0BBE101F38E040707F735E40070899DA08E608027B818A1042946E080340ECC0022762E1D2691D2A3A58E1202\n"
+":40AA0000D2B850BCD67C2146F22C3F14660F683CA80194A17701563354DB237629D225C01F78CE2E0184C148660C801830098360801009DAC21C1860689AE088D60300184B\n"
+":40AA400009CC1AAEF44D3605E720ACD133CD0346FBD33FA39133101093B4F0083A689986C5A200DFF1413082A6918DE7415105706B1102029041A9E26E9A263596D02E0E9F\n"
+":40AA80004F206621E3D24900F06B1982980602D97900288244D52C88DF2BAA0F71CE8979A06636182B490C2AD045F0B551143C6FFC2017BCC1C809F878546B74300807A76D\n"
+":40AAC0002188D62C096057C411822097042599D129718E0D0202FB106195AA6040AD45512880A25A91A20D61451B290F0EBC110B89DD96AF088210177C561F0F510F22657D\n"
+":40AB000010548D9800E6F088308A1838CCB143D99F440A8042285C40051C080C40406419F0B650F0AE242AE0C9434485570083562396B1244D023B05F410030605C18206A7\n"
+":40AB40000020742EEFA02196251C373700EEE98E80182D540091D82EF174008E20D788FD1009C2FAFE035476363B6D6CBD862C3A00B1104FF21CD8078FF37CC1204D80F06E\n"
+":40AB8000FF3BAA240FF37358A030C475A46C982414289D291AFE987C235871D8000483360402E08FF4CA1976BAE088110980C9010DBC380A3DB6642010428E9390F8D2099C\n"
+":40ABC0007821208FF1B2761310C120D234D460A43359A0A2F8C121146728BC40188D1B98F53B08E11803282FE23923E3C1510383103C783B870F049E883E45ECF124139940\n"
+":40AC0000E099D60A6E6EA3E504F1918842A7C8F487B5EFC861067DCC505BB9E88BD50406C8063B6FDFD20A10038044048A50E43D19DEB17F193011FC1B188D30AC7F3F3C2F\n"
+":40AC4000EAF04599CC5998E59F51EC09667616666966076B0B8453D2B38907B1640989E008A204C82D8B34B49F42090C25CB0C302270C60128BC9F045AB2791D42E283D04D\n"
+":40AC8000A1890100D05DA76A2607122CD80A0FF270DD3FFB5FF040E2F408F2A078F95024801F8A8F444FEB92D13882EC8BF2018B8023D3F2020F8EE0804FE17B7200F8C1ED\n"
+":40ACC000117C53D22208FC678F262CE05300845A2AA324BAB7D842F0BBE0EB23B828CC4510F4E06200E8158BCEC508003E258C228420647FF3F88256F610034BC043823C44\n"
+":40AD0000CD70B00617AEC790970F9C7E88FFF42B32106221D5708015722068E245DF9E13F08DBDB0B243E97BAB612248051EC2F1E01C1D7C0A6665900A818E300F5C1B24D2\n"
+":40AD40008F6F82C70787560F32E3200C721A07A13FD905490F222D1F40FE3CD4062480E3F85C30270071804170C1E994F3C96A53B4D864DD004B0EB5E31F862F84571C0ACF\n"
+":40AD80009D19C08ADF017A0DEF601666708855ADA91144FF2AF79A0135F7CD733E8B103B924C0F11591040C11E831DFF712EBC9C1A0E1F00EA0F053D40B9020760C361A268\n"
+":40ADC000112CF611CD9036191124F6027B61FC8E5392CEC0799AE74808769AFD70BC470903C6E38B8E978F698B980C6A85DC805141682EEED259A890EF78B123BE19AE1073\n"
+":40AE0000AFD0DA059BE6206EE1BE45AF048B12D40A3604CEA7E41004FF094D80EBCF49247F8475EC243A00D1B043D1E1048FF31FC1DDA243982101FE079B1F10FD89FE0E75\n"
+":40AE40004BCA5A52C1BE1802F969CA40166C182050053C431E551C901A7320201FE70F8771CBAAE48704341224AF5BB00FC53407E88F612C7D90F8334012A121FC4F5C7CFB\n"
+":40AE800007379C9F09838447EF4782372AEC0C000FC5732208809D756020292A2781D74E892A381B1DDD5C25C9167F1266C1066C9587F1DAC1406F78B0704FE3AC053C670F\n"
+":40AEC000502B4C29D047EA603E65E11CDF2103BE019D19B00803643440E4362A200A03F8E24084364E03F8E1A4A2029FC6F9B0521B33C01BC6C0746C8007F6D06C30623F26\n"
+":40AF0000DC2E2C8FA8030A1F10201B343C08F3F87AF6F6508847F0F1062221FC3B9A2449B023203AFB71C04302E48E3F873344873604A3F8723604C873B6745BAC04E3F83D\n"
+":40AF40006E363E03D81030133F86C34482360523F86BF6F6B08A87F0D26C0AD3408D0688F86C0B07F0CD4742C1E20D1FC324388B880C6688F66C0BC7F0C3062301FC301A91\n"
+":40AF800023A20311FC2F1B1BB7B0B02EA033285B346E5F01A18168D11C4D81A8FE160D81B28398AC6C0DD1A22A9B0384188A6688DE6C0E47F0A468CF403A3175B80611226F\n"
+":40AFC000279B03B1B262972021FC269B03C78200C8FE12CD8218D99B40A5360883647040A4EF3401034950CCE920C96092CBA22251B1DD53C5810AA8442C409D360853648A\n"
+":40B00000C03F89BAF31214FE287D6EF927ED4989C6812E825E6A1258D8260D9A800250D8266186AE038EE70B048D4F8C900903607A60072E784064F9406640FAC8442F5018\n"
+":40B04000A92063DBA00244611123C008C1FE5C835C80B11817F20E1909B60643285080B3490CF0931DC286040542A13F0A501E46F8D8482D88068074070C40B9C1E449B2C7\n"
+":40B0800063C5686334856A005C02F8218442001CE1D011089BA8BC163D593E85C0E15F31F0C3989427F01C12F7A2B21A30F2F6C440F14C4206C583DC9C882034905109C147\n"
+":40B0C000046A458980D9A6F01B8304626368006C0FA147B3210420F83FBCC750C0D107075344A102CD805A7F1019AD9F1867F03F4F63608A3640D3F851E206A88F76AA4B17\n"
+":40B1000001C0E813846ECE44124B86140FBD6E25811F03808FF043E43E0A0A07064728828411FA442288608ED4C22C074105CB8860743EE5242F414B08145B545802E776BB\n"
+":40B14000F84A376F09AA768E381751CC7A22B4012B42064D1EC1831618CAF12F4E748E9D3C7CABF820895A03F624B883E6B9CC059C5DDDCA2C71F5F236BB54B04DBED5DF4E\n"
+":40B180004CD6387AD9F061C598C0020F7204DF8754CD2010990766E221780BB9540201BFB1D50F0B318052F480C19818380D03466B4C004F0B48812010D36B71C9CA302B1E\n"
+":40B1C000D5D9E39094264AFA812058E04F1E7210187B040D0D88004D12DEFF94B25404BEED52944EE05B306502EC0A0CB3D8C990080DECCDE430F4C4207BDD20713C108C43\n"
+":40B20000B4070341308881706B1F092340A7C41E7DA99699E01A9A255627D549E4BB5E61020D0291B130D0774134A251813989EDE408DC84B74AA50164D223D976BCB24530\n"
+":40B24000E2809A8225D16CC0414108A209E6425A0189A03CA00035F88B24470A5C61028E31231C713D3C881C5555122350107728F019D11A713CAA33A60018BD9B14889D4E\n"
+":40B280006BF40D515313B2A6202E2D21843005C68635C13709C88A593E8C1A024E663950E07A12F21758C24A0C02543511110149911D90BA24662747480520E9E190FDFBE3\n"
+":40B2C000F7EFDFBF402AE856F11131E05E23B944480419625E22611C0945B113CF6AB821C6B790B34417190C0E76AC9A206B1BFEF245505C81A06C920139AA6CDC0458472A\n"
+":40B30000E19C7C50699B2C625F036580041736476EFAC9136803CFCD22B7BED8847EF2F9B09AC6AE88886DDA006DBC08BA03071020D73480F32816EC7971020A2B7189A10E\n"
+":40B340008D548D8B7089A4671B601B7F189D901E55480027E64B03A24B28D0368F1960810741ED254CC5400165EB30516C18593DDA176D26A01593069FACB21CC086817201\n"
+":40B38000C1C7566B001815A8102B7E115E22982EF2E0E09AA535C5CF220596D62D260DB60963489FF8C85874B9E371614D80C138A20592CC899D943478819A05A85DD5B6CE\n"
+":40B3C000480ADEC84492108D0073B59E4C8118AE310608D449D0059676511BACF758C88E2C10E8C61B63BA5F04138C608CA6B0FA430406B8E7DB21E2009A23F5C46E4588B4\n"
+":40B40000D8E065A256F7892096A70B24680994DC52E111D81C8829D848D091D0C2463043B3486C20987271B8BC188C1ED0B91B88C46555911345A231E2109A22E5C24C45D1\n"
+":40B4400003881443290AA061955108342A28D060B1487BDBF10010A1A92400C0A91C2C8A1A2239AC255C1A221AD9A4191A01B16400DBF40AA005010480A7601AB25D0148DF\n"
+":40B480000B1DB2FA60D4EE8874060B4A5DAE8C9042BEC0305008C0A47EC804B7EB8F4022FA30B50104EA0195217040AB6DE13D9444C0D000E0A2636E043997E1005A67A152\n"
+":40B4C00001CA4F357E21E4A382EE87E1D15F0C108268DBA08F0EC334418EBDA1A74400000300038C000000004206000038000007DC001FBF7EFDFBF618FE0447810E95F7E7\n"
+":40B5000096343623B885A001A6202C0A4E29E2C3A6E44B251C11626E2D42121E688A162083715E317F720320BE174DB24A8521175E2F7AE302DAA0D20277174C376942DCF0\n"
+":40B54000F5CC251CC2CDC858C4A1D46E080320D0200CB706D1B8C60380E8320DC3A0D589346E59C2136E31EA6E57FA6D827B0479220884BEBED04180C4B48443BDD308073D\n"
+":40B58000E06B02210608E50497639315832855C2A8382987CC76C8694EC80848044F2E902C90BA11CC0480C4F6DAC10024423CEC80A10BB5C089B108244664A6026520A10F\n"
+":40B5C000400A4348C47A0FE8B14F5878900A9E769C5145E3CAE200439A30F2FBF7EFDFBF7EEC4C1BC6F1AF76A2D44DD450CD6F00E5BB701EDB3C20056F1EC655617001BA16\n"
+":40B60000602017656E9756A10F50D91F5AB51625522CC3364E619BA5918B72069D42218D2190C6106C8BD412869B5C4D801B92E37B93423B9303CF901F2D80B97FDBEE4817\n"
+":40B6400009EA2811D931C69940EA386E7314360C61C0721C064188643C0C90E4320EE1C86E1886830C2E21C06084290C43A86C1A0641C862338EE3D6E76263586FB0880C3F\n"
+":40B680009B20E4305098CF611C9186639DCE41E57DC25D6DC058B6FE5FAA493DB94F3DCE668780A6D5641E07B6AE4057DBA8D7DBA93AD88FB4DBD51E142BB002DDCC9CFA68\n"
+":40B6C000ABBE76EA6A027733AC21C0531176F1D560C36ED5289480A8ED3656A1D95A0467A5E3A7C1AD9E1AB4F085AFF4BD411238274CCF34314516D8E480EFB15616C83A87\n"
+":40B70000AEA31B3D8D82475DB112420D4B26437EDEE88041B4001078106C4F07266C6819765A73937D9852B423C8DCA32C0142BF5D3048981D332479FD2D8F072D8DED9DDA\n"
+":40B740008C716600104B1978ED88120180C01811EB8F11131013830EE4FF10C0060C0080C00A0C00C0C0120C0180C01A0C02A0C02C0C02E0C2020360C2C61020061700405F\n"
+":40B78000BC180C018145E38C291E8312B100203318833D5F2275FD80BF65746701DC0194A7B6346C9B73A9553A7C5B7D59ECB9043A6CAD35BAC8E017015AA9256CCABDAE73\n"
+":40B7C000EC39C44C2265DDE230730EA11D00492361AAFB8B4BE36E2405610C4DDB626C41D85C077606C30D0C31B061507BABF147CD7BA36F281A031000680C90EAD5211CC7\n"
+":40B80000396F40865E8037914F7AF419200915C65BCC5C8D2310E5BA43A1BB69D0DFB9E22BB77188D2308E70C90DBB6A1142E2308F0A3B13550EA31A1BCE3D33727053C551\n"
+":40B84000ADE5A35399B1BAF118002789229DB51210C5611452A2B988A3C6ED293C1CF0610C31520C9906610200000000060000080001000203000BA800000000FFFFA1EC67\n"
+":40B8800038000013600077E821C5E0208418EED8D2D60AC80C1A00C0110120100114157FF8B566A01BDAC130040340400248240480250280A4160A02C01301581AA0D0684E\n"
+":40B8C0000D004E0480E004EF560D409C0BA46CE5A044029A88120085F481300A6420500298481500A5C40B0046FA40B807282060034C1900D60D006B06C03583801AFD1206\n"
+":40B90000952D03C01A7D29F52D514892904202488B014C47904602C6104802A7D21422D04C02A78CAC1B0A0064C2901961500CB0AC07585803AC2D01D61700EBD2084B41B7\n"
+":40B940008011124188130C4190129EBB9A5A0D00A4C3502D61B016B0DC0C5870062C3903561D01AB0EC0E5878072C3D03D61F01EB0FC0F3ED21087E080EE18202240207AB8\n"
+":40B98000242340223824240FC113B1212A0121A12132012391213A01327921417E0A03490A4BF0509548545F82A08A42B402A47242C402C05242D402C42A42E402E012421C\n"
+":40B9C000F402E3EA43049F218203140303A86080C900C1E290CD00C8DA90D100C9D490D500D0CA90D900D1C218203740364E24390FFCEEB22C0750604A221DA01D03D21E9B\n"
+":40BA0000248C487A807808487C1FA084487E807E900880C8F8182020A4F748841F8403A244349E0182044404236244549D0182046404432244740460E8608120BF463F505E\n"
+":40BA40006049402405922524920C1025A02503522617E822830409A809806489C920830409E5FA0FE48A05F84E3D245149EC9148BF0A07248A693B522A20291A522AA4E610\n"
+":40BA800048AC80A86248AE80AC1C0C102C87E82603040B480B01448B69B2808B8C05A06222EA4884D1A80B804645F46AE84600FD83F0304061405E3C24624D5D08C6806013\n"
+":40BAC000A19101828654062A199018A8670FC322743040D080CD43497E1992C91A901A02491AD01A11A91B101AA86D406A43246E406CA1BD01B0FC182070406C7D24714041\n"
+":40BB00006E3B06081C901B9E41820734070A1D101C1D291D501C8CC91D901C9C491DD01D28794076A1E901DA87B40796C511F20C2AE847D403D50FC80F543FA03E51001F81\n"
+":40BB400087CA2043F0F8F849041F87EA20D01FA8844080A2143F10144307E20A88745EBF0C9108084A22502182A9228BF10C910C1045A0440392462044511A811405491C13\n"
+":40BB80005F88AA23CBF11544817E2328912FC465124811D449A0473B924A20481A830412A8120E5492C5F89230A49740940DA4994094A269025A89B4096A271026289D4015\n"
+":40BBC00098A2783F13544FA04D51408135450A04E5144813945187E27A8A4409EA29502828A640A0A29D028D9D04A8405251525F8A4A2A9029A8AB40A6A2B102A28AD40AF1\n"
+":40BC00008A2B902AA8AF40AB574258418345897E2B245920565166815C6E4968815ECE825AA02C28B640B0A2DD02C93692E43F16945D205A5176816EAE84BC83068BD40517\n"
+":40BC4000C517C1F8B8A2FD02EA8C040BAA30502EA8C240BCA30D02F28C440BEA31502FA8C640C0A31D030A8C840C2A324BF189465206251965F8C6A330BF18D46697E32283\n"
+":40BC80008CE40C8A33CBF19146817E32A8D12FC6551A45F8CCA34D03328D440CEA354BF19D46B17E3428D72FC6951B21F8D2A3683F1A946DA06A51B881AD46EA06B51BC8FB\n"
+":40BCC0001B146FA06C51C081B147087E36A8E240DAA38D03728E440DCA395037A8E640DEA39D03828E840E2A3A5038A8EA40E4A3AD03928EC40E6A3B5039A8EE2FC7451D0E\n"
+":40BD0000E5F8E8A3C0BF1D1478A07551E45F8EAA3CD03B28F440ECA3D503BA8F640EEA3DD03C28F940F2A3E903CA8FB40F4A3F103D28FD40F6A3F83F1ED47F87E6F15A5F09\n"
+":40BD40001DF903C45194A80568BD3261042ABE7040A28CA668003FCF50083200CE88A3E9A4AA0C827040A339358D860FC846148140AC17C2150E00C03C8058C41C09101122\n"
+":40BD800031BB7A180C13CA823BEE60A3D7181180050510866100E501464A085832C3745918430CA7E16EF9F000DC04C8C444E721424088CCE434016701460A24354398E19B\n"
+":40BDC000162D8ED06639451DF94013C218F129447E72200A13B091F1F1D09504216C0C6D0AB2486467C9231A22C6E5E661977D63141A051E5380861D472C30862208A4023E\n"
+":40BE000081DC0886CB0C6A549AB9F20440B98E11644694199A92233582F3FD30C0DA03E11037128F237930C4E001C815862401281A2C311C80201A653E0657308601004653\n"
+":40BE4000EA8754124B85F41020385F1903838600009F500300300A10C1E0002250068019DCD805005015404401C07600C462209290840A822C0166408321018F58A0487C39\n"
+":40BE8000D87A0108E30261EF52460B800D088F172017002805041400C2BC0860070042930040481BD80242E8BAC01420056600B10609B0A85021DC01A1A848500706920927\n"
+":40BEC000803C015589B0101062CA804446D30363B214E5C026122488050210D2A0150D44AB00B059221805C2D106C0301608560190C534201A0C444A806C3012EC03815EE0\n"
+":40BF000064403A1805C500F2FD38700F809185404014258808410120A02208708808C21B88902F914A025530444C2706350138808440502A6A7101489715D405420A21010A\n"
+":40BF4000585CAA040582FEA71016816B021B17404534405EAAC44600501C5018860884064182BC0D81984DA1880D02E524406A1AAA1101B0ACAB8406E11845501C04496259\n"
+":40BF800003900AE23A1012440761A8C6501E05FA9C407A17EC506C0F84058C0D81F84AA10810001CC0810473806A1B4DA0B810C255582044081491022AC1089187ECC8810D\n"
+":40BFC0001CA44822B0102484F2A1409413C8C604B5981060982F847502688884409C2F078502786BAD440A01AA9A20510D243281483591CC0A61AE3102A108440AA1AA86B1\n"
+":40C0000020560F84FA815C430D6C0B021C65605908D44102D0E38840B629879502E04AA2881756E94182F0442F140BE1C29E206052444C2ACC44C4040EF5031801B814D82F\n"
+":40C0400032038AE840CAB0022660AD60C40CE04E6040D021ACD881A441389A840481035859B0E206C59D113682092206E06134206F3021281C0495A0103888616940E4201E\n"
+":40C08000858607310A31303A0808440EA2165881D84958D103B88208540F004189E45BC6207A12766C40F604019503E2D5089F448086A07E11D0881FC420BE9E07C020E925\n"
+":40C0C0006187C0110108800840D9B0D801ACE083004140E0C01448B8300638B00738B0085831060123FCE55005010059802D4E106018AAC4180681C9621EB607170CB4212A\n"
+":40C1000070C4511724187C11103450C3E091023D61F04D60C403E0A2E18403E0A85FAFC30F82C1BC464C3E0B84511161F65318B61F064405A00C3E0D1443E0DA604438AF43\n"
+":40C1400041BB1C43E0EA0CC3C500F98080C0426022301198090C04A60263013980A0C052602A3015980B0C05A602E3017980C0C06260323019980D0C06A6036301B980E07E\n"
+":40C18000C072603A301D980F0C07A603E301F98100C0826042302198110C08A6046302398120C092604A302598130C09A604E302798140C0A26052302998150C0AA60563B2\n"
+":40C1C00002B98160C0B2605A55F196C000990865D1545528178005BC8D83001EB4F1B06102005A818819C420631D55D4819037DCE46C19417894A06600B7CD1B0670401D9A\n"
+":40C20000A87064798433489A0F540D42182F606B0817351B06C0817331B06D13560240DC3027040DE30630C3409816883F0E088870DE1FE9BEC8C340686014530D020844AE\n"
+":40C2400038A7C8DB18F8A7D8858D8625A04669261896C099D2B0C4B8092C746189740E0D098625E10D4A0C010480C031300F714F96C0301870B791806014E88006054223C5\n"
+":40C28000911E2E19A0E2D8600B0037E51B002604344080282B5000A2110180728D435FB82D8623D0823727899E189D1013305B0B62734D0600602375B18600501215261817\n"
+":40C2C000034015E8C7C5E244A86E2041850C0E68E06F3923CA5820D2881070B660313FBA430A470017A38FE484093024A201AC82A0AB200DD02AC803740ACD673481268505\n"
+":40C300003802651B0808010841878EF0A5C3B22F47093198984A913194868A682D8A8A42B4223AA0917016B095222E20083017A1111824088C4E43200004754F9CE11612E4\n"
+":40C34000A474B282205281B04058710068470D540208447C09052E162400613B24014AA26D14A4030B3E015AA1684206110FC3EB07A005014A0030E62CB0002E6142C06201\n"
+":40C380000529003586C954B402B00330C48D7798106E2802508352E961994491002C30801061A88A29AA03014145100CD06152800429009500941016836432059940A733B1\n"
+":40C3C000200C18EB201114C4013A19020C8086C5C36861E0EEF2C1602001A64162680A3080150A7E303A114C76600A1838667081A5E160080A652160080A84514004748FE8\n"
+":40C40000E166325733239002110DE9AF02C340C525801030E4F21000000000000600000800010010030044780000000000014D743800005A8434051347CD19F2680A5068AE\n"
+":40C440008A7D0C882299A4C724AC164544854F0D0408A90A81A42AC188AAA42B2856642BA85763E8715115F7A691870F47F10B02C20021A02C42A0690B30622CF65FB08B51\n"
+":40C4800030A880C8FA7C5C60800844D216A2458600934188540D216E0C45B5217142E3217542EB1F42748C280BC90BD0688BE90BECBD207A2C0C050816688C06821C46881A\n"
+":40C4C00059185218590C4A1899765AF8B031A9792C5C58191486550CAC86650CCC86750CEC8684C100024682E7043077AA21DA480011477E8A108EC083D1BED2008A41C09F\n"
+":40C50000856F80373D07346008A80223E838E10045CC5E1232E3A8909384F388CBAAB99E794E384FA3A09F87CA37C2008CFAB0190905860011A8C867A83B06F9F8F452A170\n"
+":40C5400075EBF08D9E85C82B26000236F3EA11F3814C802388D9E85FA300472F3AB708E46A23E85F0100475F24F81420FA067E7121D8476D600047BE76C923E4FC23E4B8AE\n"
+":40C5800047ED19108473008FF8C0247F3111F059ED101400B20164812619E8962160829B06E221840C80116325C0485E0C103E159898403C11F41F70B043750A2090D4A051\n"
+":40C5C0004242B1121F9757084A3C33E6954AECD62100491DB9307071080249F44C5144092932092BC9B70496F455817997EC497141AA7424C7A1970A910931E84142C82941\n"
+":40C60000926BD0CB8414420F99B08B2A0E49B2C19E29C1200939EAA282A8E12783847A26B85827C1447A2FC06102D182C79DE644A5C080213F8730C4A6E845222321042458\n"
+":40C640004A840B01A25E1280129E485EAA731034FC10BB0FAC7D02A4416980A7D7D3424D759B80831A867914C023079EE7A0782014881E799C90B0B901780781781E7844E6\n"
+":40C6800011C7ADC0C422F43F08FAA6907C6EFA5D23043BEF197799920071CC0B0C03B135C940C8760A0ED020D138C210C804E01283D588A5CCFF0B9A2809823C805D2F661C\n"
+":40C6C0002211A86E74E598F80F24424F18F21023D71BA3D0356414A60398216FA95E941DA8707534A0EFEC8244803DBECE2671AC681005010DC5BF44081282EF5F54919A22\n"
+":40C700003E8444002C3397FDD79E5BEB4A1DE77C3CF4C078B728805EC18D2E04A23D4D245108739C32F2CFA094C7000E4485BC1760FACDC07CB2462010BC048C4111C1D4C8\n"
+":40C740005E93D7BDE2070DC0B081DD9D85DD9184068440B7AE3DC4D12E8B8140B1030D12E4B10037F62400E3882D380D8F05D4A85A7498489205C9D9D79BA5C038C401F090\n"
+":40C780004D611E40E9A258132659321617DD331E3EAAD9102410EC8702E90749F50D70803EB1E132A51030C605BD728E87531718185D02DEBA5C3358A3EE8C41E029C4C469\n"
+":40C7C0007A254F6E3C9304D27DDD787CFEBC40C23A1CBA71AC4C21F4B6188BAEEEB54A524C81B47C5824C990FCB9EEEAC46EDC8AA44BCD24075E6A98254F80A10B82118F5A\n"
+":40C80000821687C417C3E02892E1780258F8512479FB21733C1130583C10103A188CBC647420AF4B23974A391766901F4181225121C9BBC58F03460901C133CBA104C79611\n"
+":40C84000EF08E1E41B4209FA7394C44180381A034E7E2A220F8FDC041A088400C059B108069D1B0C242883E7D79106021EA01A12E7BB78468A0798F948210398F015F9F659\n"
+":40C88000E3009524902681B7E0A7429A1737148F4F3BE6889E5F8A037943D70D253314C89593C414EC9C51B258085E49371F2B29886A0BF69A299E9DCB8E3C20B4701DC75A\n"
+":40C8C000685A972F2B109C0B14AA78B9FE09053274CDA0024CCFA646CA4A01327D06AC5D36623E99D61087CF46061F9FFE09D922E44EE92E010580520088283AE1404101BF\n"
+":40C90000F7BD144FA534845308580B85102CEA05BCD782424B056772BD9737CC125C700A80D2782DECD30102CD2ACE10BC8130066077A417648E892E87B3128B8C10A00502\n"
+":40C940005800C60F59C4A15B1049D6DA1DE7544C9700330110C09844BC4871DDF0C40606D5CA81A3E609E1AE732D4E8014B8187D078B210153E65772EE0522178D9BCC80D5\n"
+":40C980000B017CBB16258051D5ABC88E96F82F431E29CCD28CDA48CC4F3BEA2E4D605E6FFA2E8E162EEEF04BAAC90BCF66497777E0F79A01FB061080CF1EAA1049E64A9116\n"
+":40C9C00033FB51CCB9DA21723D03EF3D8160E3F27258F9BA367B079C4172E0E3E8C7B30381701820308D1378EAF2B198F0F5C1278B822B99010809CDFB9007F938B09A06D2\n"
+":40CA0000C750F89598219E03DA2071A26AF112020347E0B7B267849607F7CBB32FC702E0D0347AFD747C6AC24680EC0D7111C232000E223A97111B2278AD1FC60F1E930E21\n"
+":40CA4000057032483EBD942000830847A157BD0247BA288483F1A0788F02A794DC06D343E36D420284EAC21307BD0291302AA0402F35741755E0974609883C6817A4C04039\n"
+":40CA80006917BD3E5A5DE0A8468979E36EB28532E91F1A1A133D16D85E9D6B33510E003C26896B123E9DB21B808380AF1711B42A83400117FA77608F0143BCEC045D4AD45A\n"
+":40CAC00083DE75823E21E860F12EFBCEC0AC601EA6AC3340A8EBFD268344CA351F8C8A1747E3027587068945A6896042A54C7447834B9B44F7314213200091A5222A9243BE\n"
+":40CB0000AED54B890B151522E0E73C884E84402097A10C042282161AB79806B083040780E4681086A909CEC2CBA10D444D4FC59B89F4CF209E8317421B97421708854C12A2\n"
+":40CB4000E8429110E98A1D08462205324C71A4C4D00F49481B330B1301469B0F871D086AEF4123323B4ABCFC083024B02548CC43550582204446E46B254958E46B641708F4\n"
+":40CB800000100DEB710160300641538B9C680F4A0508F1E5FB31084141F8401F41C2F43EF57328885D64424078C40B041E502F43A3C74BC40D444C020381641279437C7B79\n"
+":40CBC00060ACC1F29014E3CB82088EA156FC122158127D05BE3A223F2363101E2F02DBFF6093C19F7B0917AF518A6329A83C6D7820B8400813C1A759631461804A3609211F\n"
+":40CC0000F7C20AE7C3CE845E27837ECB9F1901DE2A0DE497C89B1C46B865BFD3093FE64B21278A7280F00639CA291A2177A91D06741EF4591EB7EE2E90A5194110FE523457\n"
+":40CC40002E54943D092C200751A3114E101AA1293A0013A11782928887EF48A30388A92113A109AFE51D51EE2774020006C96881A8D0813013EF5282EF50C42DB000402125\n"
+":40CC800082D90EF0E030311EF5102E9EB82E7BE441C05D6E8104910E02C841040FF3F07D0C3AF5190EBFCC6B9FEA25D20503CD568FADE210F578E916E01F4C791700671049\n"
+":40CCC00043A85604093A01F27835ECE9F10AFB982C788CA8814118044F81C075332EE7D4400D33A8F14A07C2F2A3E37F02E8AF51B4E096FCEC3A7BA2307956B8C281E1E79A\n"
+":40CD00006C83263B26C06AA4F114C1BC040620113F5305C10006F71030AB34C2EA982034824CD1ED1E81E40F33CC4006A64B8785081BE5D222EF3FB28811072F7A44D3C08A\n"
+":40CD400042EAB5B23D03E340E5F18CF8F7A0611C880404F78E3307D3B8D271FA21D4B7C661E6AC420479B15048628CE8060D737FBE6FCB017C77A9F98440B7AE51D01340C5\n"
+":40CD80008288FB13C1720C178C480A53024F208ADAA361B027803F566F0F652908E0210EA1155F00EA310EBD98E476051F1150093C51754C9098A50785F7CC062D42D50FAE\n"
+":40CDC0004EA4105BC597942BF85E78975D248021D8EE4404FD2B0C3D41F4382880201E0E21C0DACB0CA034DA863168D02E498EA7A61358B4EF6982C0560137A15E842604DF\n"
+":40CE0000CBD2409E08FA626C6C706060E4A2018A914011D9491605E5214F98B3901A494CA7C8B5C430400D21A18AA48026E8ABA101B9EBB8CC412B067BC50042E94A3D3C04\n"
+":40CE4000AC2C00419CC685A04CD2268602E4821002402425E11482C7501A0F446B882BDF8B640A9E9D395437C18027E4A8C1B4C08181156894C022C503480C03A25114F918\n"
+":40CE80009728816060050E43B011E4D023B401F4FA6A14C01812FD73984059C561740D02080E36B09209520504217907D3EBA8753920894059851E88F60717C88EA2D1A19D\n"
+":40CEC000D70342688F450181C59E8480F5AE38CBC06E4705289B5EB3B32EA14728731680C15A1027E0E98B81A8210304A467E0E891118620F9232470388B81201D3182000D\n"
+":40CF000070D51A6A84885EF1EC40CAC002210360E99210038060B5189FA75185C41C0C3BC6E50010ED0B783A826061955D4A94A3A8D3D3334247245E42091E960220368293\n"
+":40CF40002E85051344502042303CBA08820EB444200FCF6A03D84FE4019023307DE892692324E41286087A8BC08C4290C0E99B53312DD424E94BE953740D19D950C9570151\n"
+":40CF800060133C449443A00ECDE616F7ABDA65A0E00BF922A48170D021107A12A8400EF5472E84002E0E503D2048382A8408EC9621881ECE3A3E83EC1343D31DB40982E021\n"
+":40CFC000C749711037D07CA3E100512820858E83DE2EE251163A0F6080D178FB0BF8434882013739E91E90CA23C89B35C2125C3C3A409B459012792801001A0970F8E9F499\n"
+":40D00000E3C0C519BC9F41B988033998508F88AD48970F4E90DBA3548841373852C298C307842F1E0560B910000F4FFF220A18972F0F69694F49F88F711A0DCA024E78ECE2\n"
+":40D040006099E8456332123313CDED8BD723A33BA16813602C52A302C74CC50B01FA00648111493EABF910401B292618030CE3EC0F35CE125F96400F88B308E902E426177B\n"
+":40D0800028522160AC2CC4025C22A48982CB97248B010C812020F69F5BBD805808D002D88106B342E120697D60412A47016F83200F55361182802C3C081D06E45D09405DE5\n"
+":40D0C000EE60875F378803D06FC580CC4BBE83751C06405D7A18C04402643DC08640B04DDEC5A3D265240C1A05B7A18C4BC33B87817C0B4042248B387317F99A10C3404409\n"
+":40D1000002109E7655108017EED3C3F0A4715840082003A1AD07C2DB621878D484884C86512A7A1AD0BD0FC45D34E02201C3E44F510B7D5668510778F8302A0167927811B6\n"
+":40D1400043D0F6C7A0BE135C9FE219A8EB2EE7D026056201064F0097CFE045734C1664015E010EA6481A0A82641CC02001C032018377ACBF4808327B3984B9F56931D34782\n"
+":40D1800046D0A60C707621F42678901CF8D8BD01AC40C1411024E10087AAE6C480D8BCA40A04E7744B8F2E8A082DE5EC5134083EF48C9C3D821801C09D383EC71312440378\n"
+":40D1C000057C143CB00C0D06E1208020404C20DCF4155E37F28F3F822EFDDD1C1DC02B5D9A5679237B9C7D0FA89F8BA18F04803C3A4758648A30115B088F0277A3D74BBD17\n"
+":40D200009C48B90340F16BD3C3040478067679C8DCCA87A868C44D1943D930742170917359804A73501E2789A198AF2079DC0A9C11285BB4BC522C2C0400A61FB008820EAD\n"
+":40D2400084F228812480B31A186C1A5D0CEE310240045D69A23358885E789A2881234751C26F2EDDDB1128F615BB0BF4823E6ACA23C984389253F977B4F99A92D1F3C58972\n"
+":40D2800001A3A8A525440A3D84A44B4203BD190A90149487512BACAD487A04FD0DB637D1803A3D0045D008050CE000A44F984070360803DDBF385C224CB897888A57A9840F\n"
+":40D2C000C452008C117BB08D09CEA4507027BB4010A50F742A20F0BAF18D302E52956D25DFC8E20D56B95FE01282EB3091102C1A3D44E03D93B6239612811025C3E82972BD\n"
+":40D30000E73886050ABDEA6721077F0E17528520097904691C4905C9978BA0908CBCC0C05DEEAC589810EF7583C4A85D04AC4780F2215741CD83EC56416030267A580C45B7\n"
+":40D340002C00E555C002F50291045C212067B2203BC824AAE43A0224BD44F47E7F971600DB250E04D806C13103AC3A8FC297C365B40092E9303848F4AA8176E600866689C5\n"
+":40D38000D7D0C323E8B4E12E4E53D05602806AB5005FBE4A87D03DE5D1FEE2608D20A045DF9AC7E40AB1014BA0B02AE5FF477008D0C90288308C63C8931052D1A457803D7A\n"
+":40D3C0008A085E719A10006607B9FD495460F5D440FA0790A6B139B10E11E41575CD10E24B11F422980BBDE3044D23C22A9B2C06E1D7CD2220F50AE8F73EC8FA660081501D\n"
+":40D4000007AFB84443ED79223650384800108A3FCC2B0281EC6643015E11751830DE42336A13491E08754490855E71D42C16836B3199CA344C8A804456A7C542C40A59A83F\n"
+":40D44000B2F12CE8F76FE8FAB12466313DBA819C61087E08A3C80409F19F002E1604226F0CEC1F51768F62DE0F61AA08101F8062190E027A8C6CA1CC334BB0B609C4234B56\n"
+":40D4800011C9B802E8DC545E98E72F271FCF996304F0F2E920F69A00C500820791D104045F143D87E6648200874456101055440DD463E82552C161011761D19F42FB901004\n"
+":40D4C00049430E1782F44E90F887E0486200C0624E3C5D447C4A3C20831C1E0C482022E011F5CE788B4040AC1177CF7CF602A11A03C7A1E6CBC67985715001A561FE2159D3\n"
+":40D500005D2F46709027D87968003EADF732B2CA22547A9218FD02E2A5C7478488BD4A1A479021E86EE2EAEBE2A103D851A3DD9D45D397A385000589410420480C20DBF074\n"
+":40D5400044204E5C8100D5C0840090E0383658169D40563D87E825677C790882018C727110087AA2403148099E49C3B66085802902A1902A9BB34827F329F10CD536604A91\n"
+":40D580003DD8183141E00C71882B8E04049095520F151C10CFD07165EBD1112C0053F468EDFF01103BBEE4441A305EBB8420AB863F096DD86224007A9458BC81FC5855830A\n"
+":40D5C000C8BAE22416DE1EA22204D50DBA9278435A6256A01337AF2E858E6BB63D547C5916425C7980A903301E0B3C4C0221E23DFF1C3DA04623D88576200C61D8F4399794\n"
+":40D6000051E367429089057A708857850807D0E2C5E172F1108BA1107B088BB112DEC201E1CD13081E0A02021016F1C198E2F8900AE5043C7B263D0DC820C1C0C13949077D\n"
+":40D64000D094674786A98723E04782E0442DBD11604007A3C88C0F4BC421680EA16F91ED9202FC6A8046800FCF290428ECFF4403436AE1610311F18E619688E43517953972\n"
+":40D680000B2CF87CDD803C1628FB3618704DA46B1B9E464E2C13820378AB5C7B3A207B96A0B0A48047D4FD82728024F76BA38FADFA07151810DDB7587E2355234FD0FDA2F7\n"
+":40D6C0007D90269DD5A03D02C31077D3068261176010E75C604C1004C03612752EB11E279F54EE17440010E04C0102B80231739E511986A027857A91BC03F0F441B21018F9\n"
+":40D7000003D199C1C40463EC1CC2C7360388C6088484001A080494B83BDAE07C79C8235142128920891A3EC908CD2F6FA3018C1509090034E3ED4E410667000600B2EC813A\n"
+":40D7400034BA61744FD207BE09840B2868084DA2130F2398F23B4DE8765D094D60C1304301E308BA369A43B0C60B1304B763C888C00C0F00A0CE0F84424803DF34A33B9F31\n"
+":40D78000AEAA8420ED6D11184F9EA81A108B8A68988C0F745C088145CCDC1DC4E426B5C542068F0298F02B64D988E439DFA80126EA713DBF225D53682049DB3F99C2409A6B\n"
+":40D7C0005C15AD111C2DF348929D7CF0268119DB116801E7EF23DA1307A87D48B80A0F2080E8278D521C9500CD621FCD08220193BE524312D40525B95CA0F3437100C7807D\n"
+":40D800006C0FB2900405B007D257620EC71838A00EB083000CF0C13404FE3220354779788EF21780E319CA6D75A00C0E29BCBF1125885BC265100582D42E030EE2BC3069EA\n"
+":40D8400001947669D15CC2289AA317427B91E8077707C981838815E70AA20A721B8806EE2C11F1F4C8F9E2B87A105C859C6225D964C2460EE1D21EA35A1E28584680A9C203\n"
+":40D88000B2CA4213017715F8DC1A2D010805EAF19890C109A0780BB55038DDC422EE2BC5C093C48C149011C76EAEB51ED365312F882B0823CB1CCFB87DCFD5A1A240770FF7\n"
+":40D8C000C2DC34AC7B8AF920153093451A3DC108468073D09D2877107A812F712FA43D2019B00A9394542679026984827754A2882C02DC6D05CF43A191C618F63840F4A438\n"
+":40D9000070CD800C8C40080831977DBE7C473786680419E5AA435E218D680F139FB8B08C2D482D505AA1DB8246152443B83B12024F5A4615104C0D1D47602334291A009DC4\n"
+":40D94000092376913C8883DC5808F64E00DB3840E10806D85607B98293EE192338333D0FA1010FB86A18A76804A6A01A328428760CF8F9B219137A9E26132A742009771655\n"
+":40D98000E254F44C956365C0828D1490B06DA672AE9487AE804476188F13A0D52C4C0207D5BE22035D52218F70C69F716FA007A446202D4F818E84D0E7FC43E01241058E43\n"
+":40D9C0000E4EA42C1E04078E3F4AA347B8B753024F7EEA2F11DB921C15142A745DC5C2F204D2C0D318152813DC4D64061E40A9408F13BF104F88309841DC59687835FCFBB3\n"
+":40DA00008B30C0011502080D254014741FC1540206D2010B2F0AD41783918B2E704DBEE7FC4458EE2C4100D1F63238B2601CDD02E07CD1044C0A263DCB282028865980151A\n"
+":40DA400054431074789D3DC58AB61D40A044068640A901424C624EEBE0B8CC40CEE2B11207C97F043C819308F729509C5E022E103844028EBA6A177191B5D1F92518000AD9\n"
+":40DA800024C809C8CC07A91B0CB10100AB398FA2AD0FB8B092170720A90ED03D1703A4053158081C72E087D7F625DBF1C361D0B66000691004975ED30F0ABC2F653F8F7189\n"
+":40DAC00027A65F1E80478DD0442DF27CA178EAB8415EA6182F1D4219F3DF3F22044291BB788097A4677D840953C46888B8207C9F2E57CFC04008DBA4FCD8E245F1E40245C5\n"
+":40DB0000A3D35762050B766F0E8F871F307D0940711E814743E59981D9D8446D772581067DDBBA5D9186368F010ED2216180EDC071EAB0F1B478D2A03A513C012B7521DC90\n"
+":40DB400054EC37DC5526012C03A040A6D026C7586CF5BF90CC22061A1DDC205D4B3E24C0C0590C00812603D8747B8A9041C026AA84F0E57EA278011DC546C01279DADD10BE\n"
+":40DB8000091EE2A54C0A343BC2D07D1B6E59A4C2350EA4455610084AA1B1E0081197983E605A2DA68EBB813861805064D03D3ACEE88091F826100D03CB8976978859130238\n"
+":40DBC00082DCD634C22EAF68484A500D41541A074757B3A679AA5CFA07201C4D02C501B21966FB1643B0841D5ECCA8949846CC4A6C44B804591A5E178640D6F5E81974605F\n"
+":40DC000048F57B1BC049440A940BE04915186EBD0FC62C17A07005434441EAF62400927ACC44D180A03C1FE8E8CEA1070D72CFD96445D5CB4226F5FC99757B0A00487D339F\n"
+":40DC4000113AE04F82BD82DC2174411A3DC54C3DA24C5E8BC6431C90130504109C185E40BFEAF5C31F557ABD09371020F2979758829F57AE11349000BE0F742C757BBA1DE5\n"
+":40DC8000E220413F57AE26041852806697076C470F57AE111C3C96928172008BD0B78D8126050C416F3B3054770A3D63C024374B588F97D5C42300BC0F3E604759872A61D8\n"
+":40DCC000F54588986308F2D7598E9F717D9F5996291E881C78A3D8F78651B01D7AB3487A986C40B2FBD666223CFA237880F0C7C54B8308020F1F01114B27847A9C58802EE6\n"
+":40DD0000645680102355615D26170A874C3B88E5D82DA2301B23F1E01C8EC09707F1109BC1220593F05D35CE219FB1C4887D2CFA07BCBD17986157A0A5665820419C89E09C\n"
+":40DD40000C9A2291321575F1D91720474888197C0AF720308EDD622644D22079CC0AE73188105302A4078D718BB2B84423E2C265EACDE1C4F6027757F68D92C0443648FC50\n"
+":40DD8000A461203CB63480025085BC26C11024360B7B6E751EA63443A525C7B551C4D00FC020ED0C66E013F8EF0CBCE5EC21720009A01E9101017271F63894F65CC89601E1\n"
+":40DDC00069A21D8E0458160905A81B5DE48C408FA502CC55204601A812204242EC3E2E43EC2DA0381060581A00865E0B06100CA0EF434238C8104BC2356201749A189546B8\n"
+":40DE0000C76B7420207ACE88448402AE21CE254785DB4BB53B842AEBA501C5D5167D813BAF410410ED7602881EA7551EC49B13250F42EC0B02504DD1ED24C9003FF5D0F947\n"
+":40DE40001005F07DEAD4C2080562540F03BA699C79E40885C3C07BE1781100C2EC3E204182811062279A00C0FE0217E070F672CC710C1DBBBE5CB80082E2D33F68428641CE\n"
+":40DE8000A3D2DF038E4041D2219D2770B013638C1098EAC99210A11C73840A753182A04109261BF0040C071906FBD4F91D0240B07F9FC3C1C967501EC05BCE47A69C07B3AC\n"
+":40DEC0000F879A5297919B47B49944BB04FA9E54E8E87A045C6940D1F0A421480B87F210FFECF822EA9C22213B65A90A3E039020031E56B2064790F4951BBBE4244C30B3F7\n"
+":40DF0000D17E23480BB6E74A9090FCA03D8993B90FC9880A00D1E78E91607543CABEE47318FB6B3C9836D9100CD1B1B88246061CE0353BFF5889E0180E37815EFBC392787A\n"
+":40DF400027E87A11037A7848C01274072E0043BFD08CC23C9D9320F47300812088400877174A10E209045D2F2289E9D353831861F710B81104F0018610E87A153139974C93\n"
+":40DF8000A3A22502A300F40E13A13E795916A03CD21D9834880E4F051DFBEC4C04E03862161C060155E255020B0C0F48D38F1C0A1E645C46094A0503EC0A269961D371C2CF\n"
+":40DFC0006B800291360801067F4B1B094BE9C92331FA0F244ABB9C20D52ACB820CA30000A287B9338B3B144A8ECBF51104D62A3B3311E53ECCC12ECCC53ECCC3689B533158\n"
+":40E00000D151A063006301F5E54AC1E6E50241980309B7D1FB470A040F58D88B43D8F81305E48083D87189760EB91702116A05759AF8C18059E4F432F3754174FDF8C38064\n"
+":40E0400017E39ED18301B7C6AF43C44C47ADC8CBAB58440B3603F2E0082D40C2D40DEAAAB28B001871A78252A3C429078DFD0F4E0089BFCFC3C895EB759502AEB75631D9F2\n"
+":40E08000207BBDBD8FA6FF87ADD5C4F840734F1DC21C9CC202FC261823872DD73187C90B87DC9D22680DB7C01F448B90D924432944AE1E160B00C4060342CF2C9D110C1681\n"
+":40E0C00067B41F8EEDD0F638A216E543B579E7AC3F4430E8BF51ED0204880E049936E0116C88B750EAC2658F02F494309C68780ED479C691F84EDC7AC740706C40A9E45EA7\n"
+":40E10000F1008D114C79EBF4B1EE21B13CC8204BBA83C7B715083F0050EE9D013E49204C6B04CB81A0D2132C5F068873A0A210389E4099090D712B1470F53F9084A0B0202B\n"
+":40E14000678F47A165D94C838CF478E1B196402F80F344E634844048AF01C40048B0E8DDC1088A107063074BD013AA250BC9E9A564A0EA52022EC04048B1ECCD61230B03C7\n"
+":40E1800000681D3B8CE04C004ABC8043F44E40F8ED7C7B29546B3400D90078B88862C0B34894408035829970C4091692900602399C1815102811253B29078B8A07D20444C4\n"
+":40E1C00066F52A08982061D5EA2D112A7AE53C40EE360426481C31059DB2723D72B65DC0B623702BD5E625D5B6A3D118A40515574F17535C08303802208161D6A9C3DAE344\n"
+":40E2000083D570421974D8619388831A00010301847CE09C620220A7966211CDF433011EF05231133850767D2101CE4930EDC0B2131E1D5080A0398E8858031102404E6D4F\n"
+":40E24000A48769001E5EB0DD9F1D4A202200161B5B50AFFB09EC61802A4FD803625E9AC5F79B4F4BB372C4CBF2800098E5A98A049A40A8C1D5BDC400821DF26A5E590B1A74\n"
+":40E28000FC064E9F2515959443D24C42021A259789630874CC4932D4062540687558600856E3D28601952161C1CC2D98028B29F4B9C0291A2506746A1D2E245E24CD3600A8\n"
+":40E2C000A14815103AD720B8A0735780858F90BD9C494F2523A03A8917E4C302F01C31F94084801198792887F0B867363BFC7CBAD1F84E6EB4622E41A643D09DC42A040FDF\n"
+":40E3000000C631E42EEAB752EF36610487A2887A13A244A3E146C2210FC671E0050F5DF51223F885D660C6060FE77744751743ED8FA17644B2354B23DCB2060F0E2C605706\n"
+":40E340002309641BDFBC146A0B22E070E799C81D21679E60941EA86206B8E04F825E61C240E801BC332C5D71CE88D6AA7917FE265D1EAA181C6AE233F5C732233264F06555\n"
+":40E38000D08E65987E62D55E113C1A761C11754EF8E891C49E04FAE3B1A2D417C4D240485552643CA10E1E265A1EB8EB3348552692000432C8203485326B90DA9428F51690\n"
+":40E3C000E88EA7B212803584C2D437EB8E74C0E343ADE1C4B5157B8F3249CC17F1D70AA87943F44383C064EBD8E22781E34C4506FB259249F1A09FEC7F91E4E8A23196A008\n"
+":40E400009F2FCDAECF2F1F4275096A2C13E03E7FF193A4E86A4E8A64E82F72F876F360E3028088B5048F011306A864E908A64F09DDFD625D716044F09A909869062BC43B2D\n"
+":40E4400020E4F44789924F0ABD70FE8659697451E098C4F8E18920D8EA9F21EFA0418B2E9E4B10407A1B8B51E33D4840627CF1407F1FC0CEB8A647BD26467E31FB46B244A7\n"
+":40E48000F01E3D05DDFD40439A144028285F801DA9F4219D291170D00589801CD104BD6FF831602C75CB99001DD78A3C3CB87D3040880218D6E25D53A4975AB121D7078578\n"
+":40E4C000E468233519D0D417427E175C212D96F077E7080E76756A195D0489EFC62544140844DE257467AF800DC7ADBA44C12AC7E2CF15B00296EB1A7C00799C0AF93E1020\n"
+":40E500007B1AC0EAE40EE2600405CEEF3FD789DC9740458E8048ABC00D73AFAFEACBB8778490F022A9DD2F2079352A0A9E2F66A298885F5AE0EF460354E2EFAFE43BEBF116\n"
+":40E54000538A4E6352B972C24A778C018A090AA538016E6332FBCAA849E40D324009F389E08080A15850E11B00DA86171F371F33730F5897091E4BF47D30FB2EE6AE4A0293\n"
+":40E58000DC04F035189DE49025CCF94410C1005E1B6D105424EFB131EA9D411107132B3D307B7EF078C5A97550508871822027165DB2FA409F7D8B231C40933040D1A25C67\n"
+":40E5C0000C7DF62E9D7B0F8DC80B47C830E46B167D7492240F1365107822F1E378D8B0347883DF62625B0A84CF7D89096C2A933E061212D8562644383115C99B0581405BD2\n"
+":40E60000572808B0622C932230E44016C2D2013D2E1008718500EFBEC34441CBEC12111BA4E3AD3DC86107C2713BCE27E877EEB177A8216386020CBE1FCFCBEF43BEC20498\n"
+":40E64000985425DA82A9251410A8429F445CE3A283EB91A1EFB064BBEC152EFB0443BCBACBBEC0CA107BEC0901E3BEC0511E39C1F0909E99514C9D0B1430250884161006CD\n"
+":40E6800009466EA03A8343A875D884627D0EA2D0EBE07A41CDAB2EC2EF1057BEBD880B2A4204312A077D4D0801DB906201E4011743910F92828FA807D0E81471E9F931E4FB\n"
+":40E6C0000743D998E2039300A75FD69E3F40ECB6C1D5640F63999F0DCA26030043BE104BA7EE4BD9C563E42031F1CA89CD433213670811D408C8B1D95CC2414CA24B18241B\n"
+":40E70000175FEA8907341CCAA81DE1DF6163D22DE3A1D22F66CE8F66A00DC303DC78E2789626B086057879907315047E0B3932E896C02A07501C3B42980C0F0100A109E129\n"
+":40E74000D791CB5712DBBBE107CB7EC3EC9DF10385A8E1028B601FC5D4622742977CD1980E8010028EB0E1E212E20342E0B080EFB8C4EEA8060081790283AA3E080918A1DA\n"
+":40E7800003231CB301C44A891E9BAE1604E0878B838F153643B73310E74F220B82F53A238165DF5C42067773591B1E7DC61A2400BF7D9E081C7192041F6E4508026A04BD16\n"
+":40E7C000410660076C4911A40FF523D977DCD991A5EA25D0C65DA06120840E8D791237C1BCC2221761F1C1DF0823D7CB247A9C06A831D8CEA2358044F9E0175C1C5A3AC24C\n"
+":40E8000002BCFF448750E31E1C60EFB084009CB5447BE190CD847BFE28C04EFB0A7023371430EF0DC3427875101200D169CAD4CAD880060A3D409A3DF7A440255D97650302\n"
+":40E8400009A24AF7DE89019D5BD22C12BDF79E4039C7DDB8A67A0084AB61024209629081420F8C71458C98D2EFBD04D86FB8BE50680D48FB038A2AA70364FCEFBCF6806362\n"
+":40E8800070FF3AEE09000CF90B3A248103282C449840D9420415F5B2E9714DF110EA9C6E9C037FBEA4C4CD0901400C8C2D0A00861442150EEE711602250AB5020CA0094163\n"
+":40E8C00070400F03CDB24C821F40228CA000CE99A111893EE8AC4C191C8F81CCB840B23DBAD4C874D05225E383004C8809C541CC5AE644620AF9A5BC4681D4681CC3A1CFE2\n"
+":40E90000C779027802BE3C932E2D74205FB5AD444BEA2A41EA74D108FC69E620281FE62A5120C722080AE8DD31E918E9148E6E8FF81C22200709A0810613D05022688891B3\n"
+":40E9400043A84214E0E102F82062E5F01C427BC4E012ECCD91E9C8F13080C2CCA0C60A057907231000CF440032C7D38A384FE0818040C2F2B5919D9C5BA4BBB850B9BFC025\n"
+":40E9800080DD2AC4593E85C8984C0B1C0C802CA2B2B10FC077B499849A8521F40E04EEA11EA04A2EC72C236982602DF038C8D9C40BA057401E3C4960404A2E220F73C0962C\n"
+":40E9C00067E8827CE08A4A00743C08C840743E08C44280E0F193A11305D1BFE322E13D80E278232601B2F404E42EE47480FD659240415D75A176A91082E098843BB1D11E1E\n"
+":40EA000085D11E457E887B3254402E210E5DACFE41063E9221A4843A8113988804F043DF5287EABAB19F8A1CAE490077C06BA3D5F1644F0440B903D89C831E40F2874AF5D9\n"
+":40EA40009B00A23A248260232FC448E300940230741008F42A420E82D1E8758120E34A09D83BD4ECEA2A02CEB92050AE0B3BEFC11363B78E0F87CD977DF522470CA1E8FCEC\n"
+":40EA8000991C382210319400EE13F4BFBCE09C810B8E1A0DCC100501560219D83B7DBC4E902856852B7E1DD6817F3818B0E05B147D028841677DF53048A7D967446B89E43E\n"
+":40EAC000C8B24F81762D0EC7D810EAFE92D1D3972214110B8BF008024F8124C86E5E8C3A0A21F28E58F7DB297978E45800C414354D03DF7D043D858330FDDF7CC969790B27\n"
+":40EB000023407BF1F08DF240823B80DC2C401677E19977DF5081263429B010A945043016E06763971131D85C2384140B733FD84842355C84245012635439802A37FB094CDC\n"
+":40EB400016101C8918890ECB8B1C56620F68FC441603306D00C1E93D5322C0C39821183BECB4BC906A3EC99D1C0F63D63D43E44762038C6050E0D14E977D8C913A1B56F91B\n"
+":40EB8000E20801F814432580436471B2882C4E86F76D14618CCA01BC58E1CF02842CEB96248160B103540D3580927812057BEEB078D4508C64B880DF5EC4960DA0CC5D11B2\n"
+":40EBC0008E8405C32187A84FCC098801C165C98830C01C254FC5D73E6801C054DC4C0744F0264F77DDB201501A7D44943975AE98F52C6893C0A13C189AE6EC699BCA018AC8\n"
+":40EC0000FAEE78980C9005630CC6500CBBEF38B01181300053D2340D2841EFBB2105455F50ABA00513550800BF7D328D4480166B29197DF768902E5202EA00AB13491E790B\n"
+":40EC4000581E7D94557A20580841795224B3B4440D09400253A921E4F2093CF5E82455202BC403BEEDCC8A48C0481A215243188B6EFBB6422CBA25F482E70008B605F49C0B\n"
+":40EC800084CB20683512611200C7813A46711344AAED1611EFBBD3E944B90542C182AB90ACF063AC4B047712083F43858985ED98012602EB91C0E9063C560047B0A86893A8\n"
+":40ECC000795D424113210619D03449930800840E951D1208B2080C1F0220484FDF77EA9A04B0E395D67D70D25916E274F7DD298146812438E57B2312991CB845BC21DE6021\n"
+":40ED0000263F6B628C63440280FFC894CFB0BDCC061669524069FC89AA3D78A10047E3D9029801F3B91098005D65096BDCBB420309A16420C88CB60B38CF4A838761DE970C\n"
+":40ED40002834117876048D5178D7178C129CE800CD61B2F000020D2958025DF9324548157FCC635A03A4D1197BEE61435864F2FDB91A02AF958007BEE6881105C623D96BE2\n"
+":40ED8000A3BDCBCF08A2101A0878F934445C4987ECFFF13A40BE44F45DF736B816040D53A20D812510423028F478B9853D1E206109A2259322EF82C991EAD3C1CDC71EE675\n"
+":40EDC0007C2EFBA263BC52E40808A8C24048B49823D0AAE893BC914880427C00EFBA133A3AC8847A91488E41C0162E00AE38FC5DE64844E8418708494EFB6C2ED3D1301B18\n"
+":40EE0000BEDB889FF27C48DA2C815EFBA040495105BBEEEC5CC1554028AEB1B13010297116E1602048201C50062C2046EBC22C115E7ADF31C5C6B0C1B3C086C0605A7F42BF\n"
+":40EE4000F00EC4FB68C6701520210529E0161B740846762203E50D080E7C23AA7618208423F1109330708004701D1751F110841623A3CC2108B047A8FB8BBEB1100540E0D3\n"
+":40EE800087CA2EE34780BB013A46AC4E3E9B631A3A3E1B852C54037268053C93F44090488B09F43E641302BDE63220913E13F7DE8242921ECABF1F502C09C1E90CA2A8209C\n"
+":40EEC000D2662004995105DA91C4C014688DE049DD717200AF7DE9220495550487276D2F548889043D76327884041CBC486F351D100821CC8405017D9A20312402DBE0610B\n"
+":40EF00004B0C8468B886A1809FECD3312DC0005BBEF607D69DE62300261F62DD89443C0E1D899C37A5077DED1846A5082C749A993883CA40185A167444B26C1EC1677CB381\n"
+":40EF40002B977840718410840E20788410841DF2CA659791474FD61FC392FC2118066881F848C0200548C05FBE524816851235127BBE5253BE30095006E54234433267CF5D\n"
+":40EF8000D0424C8134500D00CB4C8A20077CA09301842813E916FC6D1D1008DF0B143BEC18821300D20A8D8E671E414E5140887D2DF820973C541EC2963EA7E71044781D03\n"
+":40EFC000328BC8D308CB3EF9DD32CD50B30A8B3030D800CAAE333C9F66B6882BDF9382019D60A66B217820E444E34332A47397844F2C047CD64220814E85F63E346E20E9DA\n"
+":40F000003FE7F1E104BA54D0C1226048346080092C4562C417E55CA5EA0F02C33E367101642CF648F27D7F607DF2C8904FDF2E89F7DED18480823E30EA2EA50C2BCA03B43F\n"
+":40F04000FFCBA2EB4402E3C942219E0044197553A0F63FE9F64E124049141620398106B9D3D2344811E0001BE4FF41C65004784034813D944C2018F3D4D187D66823832869\n"
+":40F080000F82044026820268443FCEC8E08B32052108B2E918423AB09C0E6B110A208788D4866101A029034F7240431B7BE4DC7D90465D4F8C585AC24C240C2905802000DC\n"
+":40F0C0001F43090B35A44CFB3DC4841268403FCD6791D48842658F09408F295832E82C407006598E23C8E42CA0BF402DDDBBA20B82C456912045BEAECC2344B922420058B7\n"
+":40F100004E087C41FE239EE1A120488A03921E1C44102010D52F0E06A83D899EEDCC133B05B8780C7C4CD274E1278C2274A21E4E21F8A21F4311FEE8983F40D37C9530FC49\n"
+":40F14000BF4A570B80CC6F1C6030FC6A01667902710F4611E0350262386061755FB8B1E2C9991421049002B2CB66FBF09A9203CB5C09A0D777130B8CE103F1C44EB19B48A0\n"
+":40F180002448F2715A30449D2070E17C01FC16E4EC82388B4389758A400F007AF3F00504EEF6081E3E942088A84F4980C2F3CDC08263F985E22A81324210BC33EA94710D9B\n"
+":40F1C00040E1D831088C2090CC084C200CCCEEA1011B2503C23D6850020C9284920584C087095811651E916842423742B85460073A4201A0163DD1501883A40141E433CF23\n"
+":40F20000B41244F12CF8DD9087E80066CE06600E8F12B7BD2DC87830A4814A41A14DA088791CF55685D24C23DE4265ECE001B14C61A00EC23E38401081AEA541AEC02D1C5B\n"
+":40F2400089C9E35142C7AB2D1101C830B3D8B20A3016773D32A19817D4A6E2271602C1C20868F4C498F0F6E8834094C20469C40803627F770988A258130068120BA068795D\n"
+":40F28000B12061001504501590031CBE8B661EDFD811541B1A4B0063AED09107C0614F43DA27CA1EC5F1100080EF158118D020806027B96ACCF634048F226D083068095E55\n"
+":40F2C00044E51EEE1B135C49EEE80203CD2A0C1DDC2088A8882629F75D608AC1C02FD53CF248853DED1E607965204B43845E451B1EEE08103C9E8A101476E93B0100092064\n"
+":40F300008C590FC40E66462C58900DA12FD352E53B800E0404E2A8286081167E1368641D46BEBC7110201B15BBB82845747DAE70407019DDEE2240810354794A003CE9C373\n"
+":40F3400092A12014202CA7540622CF770B100A05A04122F5A012A4221945240477CE9081C01301B2610F825CC814F228D88300F87850762E9883E11418683B08D405C612EE\n"
+":40F38000688AE9E4512A819C0CE170A00127A90C2A697A845B4018F651008283C198098A5E813A1EA293219801C16A668797168B0B581E7DC3C822E1600C777C321DD178A7\n"
+":40F3C0004C6E3283B8F50B0C7AA9408D4BC9800902341E435CE21277EED11681302BDD0C43B1054F1C1F10301316E691E64F7254F4CF494E8381F8306800362EF73D4082AF\n"
+":40F40000C43D5300BC88582078E88883004C13264A6E99609D41448BDDCF7C22FA20D93250030099651422B290C0A2C9557C3EB4BD222017AB52D27F8C680C2580B0098BFB\n"
+":40F44000A5B7519C18300B7774B0FAD32C40A33FBB4284624677008019044162DC40020BF88118D106CA0E9BB81292082C3024183A351264C776C609FC630803A970098A53\n"
+":40F4800085B5FC823AF733E1E8EA84C4096C0E363E80B8411E86CD1D788071A91A075EA978A3044204C692DBC1D0C78BB00B601C151ABD2E1023096CC0221816FD70A25911\n"
+":40F4C00067E20E8D6480300C86058038098C65B0003A0D5E0821105A183BEAA840904C5F2D8002B020D20E15C9A0098C5DCB14213E8B8CC994003EEC931265104C60EEE242\n"
+":40F5000013D2050B05910CA2591002C670B0885DDC1257CD400239F4E918D2A50C148657E9A52148D2A3C952773B39F0BD35CE349C69595292A832A56F2D0CADC15326B709\n"
+":40F5400049C3BB3F05819111CD9804CAB8C1FBC21382CE90DC5832E9188CCEC5DA433B5C37114A910F92A3E34B0BA5B20B5A6434887553235AA8D293E8A70160825F7ED8D2\n"
+":40F58000677044B4AD421997A94A59BD02C776B39B856A08146380239F91A9CACE6349D02DD21A1FAAB4511CC2F08D9AC9430DAC313881A0295282E99B9160803029C958B2\n"
+":40F5C000D8EC7442A776E49D25400352104601E1420341A180F0C84960302C7B032D6A548CE8CA1490186801A4658DF42922DE3FC91ECFC0162ACC019ECE65209A1C47620C\n"
+":40F60000E87332476368F0057A32D44C11C422F4F9A0847D3898261F4957092DC627E4191C9085125520687306C770EF36D846B01BA75247931F08C7183A981162BB8423B2\n"
+":40F64000305121C42ED6061148D2070623AA8E010E278262D773770813D21CA22E5BB86A3C0C02442DF4816183FE83421BAAC328A870A3C61CA11064640791A48084C05465\n"
+":40F680007898D1467DF770C89EE40104389507897DE2042260983FCCAB968BBB788C1B40065DDE23E46D63090ACCD011EA05E223746584098AF7488F053711E454044602CA\n"
+":40F6C0000441BC040B40800A3C48614A7F1BEB630D44033E82602E99142C0488E0018EC8C91028FBBC3C0220540320FBF57C821EE83733F4A818C1B2AF40162789E73D15DB\n"
+":40F70000AE0481EEE081002E442F6C7F195D78110E00DD688E23E101BBB81C810BB35302510040202BC15232CF4E6D8D3A12E08BA7205C9DFE712C301A8190201A00209420\n"
+":40F74000D646B18C08112038826818C401405E8903D15C748584F0C03D0C43D0A23D09D8834734CC4780EC72043A526C8030A4F601F3BEC80E2ABD3D14200F82D0CAFC40DC\n"
+":40F78000344BAD03290FE39E639181E319F7E1B0412DA24BC56F8314A8146DD3B02D8A0F224918D6098B05B001E518E105BBA05C8200CF8F608D6B00410824BA4108262B9A\n"
+":40F7C00016DDDA2258F700D4042A600401B832F6D3295EE0209F77689588840D1C46302C3B09023046C3800784A7804648E39B1137B59DC7B7A28721CC420ED7C020104DF1\n"
+":40F8000009A307AD3D844F0BDC48E5213E50012F49788847DFAE8440FAE1A8758F28671D884BEC9779087CD95A42104FABE243BCB58646052638B102052BE94BC11562006B\n"
+":40F840008FC1117B71980263C82C0989F43C0660FBAFF584A004F924CCF8A3846140E0B5E10181894C29580081313BBB951D141640A37C81EC4071A9C0930F7729B4282EAE\n"
+":40F880008126DE96190018E90AF39011C418015981C73007B534CBAFB78792BB0825DE9C42559A22E7AC225060A5E95AA2D00496C12A4680B1E5B071EF4D6440F21A6106C4\n"
+":40F8C00046D0CBDB7345D646E4C1A409698044D6140E80D35624393BA25C061D4282209902C418821A37F100CE5F379A0F5BCB88418154791B4881A2083C31F1B8913D7C48\n"
+":40F900008EB63DF4EA25C01C0784533860AB01C3D1CC8278306CB11A0319F43C0A94C02D8626590209CD84041DA408098AAC0632E0E14021F04D211E3E174719AC08B354FA\n"
+":40F9400038C7025D8BA63DE99C5CB718582A4E0E4988401F7A67A274D2A1E45EA36F30F0B3E0971E6C153EAB401383A21F4C8600113800421B317CBC0E3420676FD111BD1E\n"
+":40F98000E6D151183DB470412F7A6F901E8CCA412F7A7021370C391C1E15A31EF4E11F048B0FABD54BDB32060D04BCD5046C5A0698323D0C04D841E45FF22441235817958F\n"
+":40F9C00088804377A6D990DE183E1EF4E040052C42BED79A1C94C10D11C6A45AA97963C0DE63DFAD49E8DF0B0261779E80F97E60C241A1111CD0C6E020223B0E40FB5FB0C3\n"
+":40FA0000D8299909070F2CA1156D079C1B0BDA8F461D6B2EC7A8DC4746B022980429970157577D905FD55D630822A8180D028307616A971F41903A1448A48120300651554E\n"
+":40FA4000D8A0E3DB25839A8222323E40771EC7861EAEFA22DBABBE4BB79A08802D7CE7BA3E9EB713E3179267B130813AA8C01CC8AC8B413100EF1502093BCBCA041111CC43\n"
+":40FA80001CC8A1F3B578FAA284741DC5D5E006C38F4F6D8F5780A07476850101A650285035DC2563508251EB008A103ABC0152B0D1E90A110EC0D0383E0AF5E223E64272BC\n"
+":40FAC000EAEF844DC344DD542A747EC43B895D41384108141A7504A173F821CBA11C3E41D5DA27DD8682C7AB97486D050D4347ABB20AD2F054FA7E88414CD2623749043A75\n"
+":40FB0000B3DC4CCCD255A9301001117215172648CE1FF6F8D11C3D963A4200F25DE9CDC4D420501E4DAEBD5F107C80F1EB29103D2F0E6397666E082BD1CDA24C41082E8870\n"
+":40FB400067E9EFE201BDA4FA2750E68668C2DD53B03D5C423DA80E23104070754DA0881D5364220F57629772018F54D99081D521422150F12A51EB3A236287174E898D4CDE\n"
+":40FB8000815943141841A20841087B66C24BA0A8BA327ADC40B8D7C1785480BD73A422C9E64D4F85E9AD529F5A9A23C7EF053C19EC8001E48272053AD954A287183A1D6156\n"
+":40FBC0000A5E4F8E1CD8247ABA556E67724788DD42C48446CA603013455040788CDA0CC23A3BA60040B28AB1C2A3C877F19FA0860086B480492B69885680B5A1B1113F512F\n"
+":40FC0000925E49EE13B0BA30FC2ACE4157729BA396A84680EA5875EB22046DC6490142F23DAB9223802222103DC6604648024F0222A90E878A0F53CE491F11A98F985C556E\n"
+":40FC4000F50259809D4F4E5DD9F0601E70898B7D5F8A83046840863B243AB8BCBAD1CC738606FA60247AB8D8FAB680CFE4BBD64101411EAD9F40E620CD013BC4770220F24D\n"
+":40FC800077D2CE18286100BAB694EA78FAB688C4A1E90EADA922E80E2E41EEADA543AB68D0049466A498F55031F56D10E3D71C12406E857D712C8812495998982A0D10EC59\n"
+":40FCC0007522C0B1FACC27A3C9135839EAD7730E4900B49600BAB68D1017965121D32EF3D930041A43262F7AA5E1034020EADA0541F55F1A588B5D86503E2A793006AB0791\n"
+":40FD0000AC6390ED3AD109C13BB50CF4212E5F1103C742C53389A05D1DE790F986303C734C2111108103E93F91D49A8843CA324BAE6D842E3442034820E5CFE5D25AC4288D\n"
+":40FD4000FA28DA451260420180A42084E4EAFB653ABF496D1DB166F7165D320CEEBB84289398A504044764081D1E51E449131B2021771E0084FB3BB084F72F084E2E33D5CF\n"
+":40FD8000B385A3E44851283CC87489DA880C62035D6B6025805E6882C919A6882A549410418A523C63B4458940688290A23627C939445E60A0449108BB5BE858268302C06F\n"
+":40FDC0002C26831EB34422E48E64B00B40BE74984057AA21D1025103C6AB8C03855888F215981D688885D4C5D688C85D443E1EE621D3A61B4CDD344DEEBE7D2F077CA18D33\n"
+":40FE0000D4BADFFD4E49E4657056E1D7B50F24683C330D03374B883817C025340CC358CCEBDA733314C0E37814D0159300618C12941DD7CC5D0A8E40A0408F5ED418C69009\n"
+":40FE400048FD981A31498DAC32A04F00FD7A30880FD2018760922CFAF69C7D19866CF0A451780345AF4FA211AA5693BDA50024EF5ED33A3BA974B160B00797C15940B25F02\n"
+":40FE80008888399FBB030F69CC89D0C9014CB9010BA01399281CE2812031076380E0A0056968498B7F03038890ADAFFE1C24A04F0505D75E5F8F832F040AF4F8D0F7215095\n"
+":40FEC000E0AD02E050B91807A0B8B6E9E8D1EBE7343B5D28438F35040811DC0FC87B7AB098230B61200AEBD9C68530AF405C901C15A1D04CC2C0102FD830470EBBCB115C0F\n"
+":40FF000000278DDC0123E3B4D11B7AF0F58D0880985D787E3998A2E6049C3A5901197AF1044652E1002822BE401A18D4C0B36AB10F9EA88B00D80C0A857DB224813D6134C8\n"
+":40FF40000D016FAF04191850F55278F465A8809D7822988880AAA21685089690FA8EA83F1F294D8812688A1A3F1314148F54F846D879F0C083A04002420E07C03BE007D1EF\n"
+":40FF8000F072C0811DC93E2200311220C0140098982C843D047B14247428E2098DBA3FF2111036347FC20193680287A002209AE20E8FFD0EC27D113DB26C653403E18479F2\n"
+":40FFC000E4E564CF879544E7342D6C0169300D9323E6897C4232645E2643D1E062EBBC3481429C07D93C8881340332C03AE6B12614857E38D25BC07D3268FABB984D30BC9F\n"
+":020000040802F0\n"
+":40000000D20C2F090267958B493200967E939E12CB06A093A87842F060800124910080EE839B1E97333F094DA3D7780212F2581438DD3175F201798BD8C7CB870424EBE35D\n"
+":4000400085361CC4BCAC345B30F0F61562170C221C069D785CBF5E1427721168FA8BDAAC24E022782CE91D1F72BD782C5A6363E032B228F19799D9B687AF9E8C270C39AA47\n"
+":400080003156F21E197812589003B92C7206B12BDD4AE813C2A766930823CD744700A19740468AF8B59D237FE877CE209BA00781A8D008FAE7B132F490F22D68B3E18AF109\n"
+":4000C000215BC0F22EBD93985E58F32EAE63202496B10976A829C39114993C17FA57D8D8CCDB2EEBA81103A6284417F31B3A33827D4C8040B9D4138004B0608846255A9860\n"
+":40010000B42F843810569880ACA0EE4D8292A9CC69CBDAF3A5A83D30AA702C1EA20893C08F96E20E71466F789604A701005CE6D002CB25F660419CB27BAFA1C6A3D0EBE9C0\n"
+":40014000F1D96288D809C4347A5AF8821A7E9CA4896138B9113B77ACAA783CFF4E2107AB1F8807390BA63CCCA04397A12E119108DA5D205B8C05B8435B015E200F80D7985B\n"
+":40018000803E04584C0B7014B711B00F98C3644500A06AECB58D70A4970A8271001A2507A0BF8F4A89866860481B1B8697AC44034429F39831B1D79D6813E05F67150DC3A8\n"
+":4001C000E0297A3DCA7AF3A873588875F008C4F47730845D796C43C1B790442741028049E0BEE1F51AE883DD79A088063DA1716868EFC872C8921B660025E42821F044D0C3\n"
+":40020000B1807409F0B3342880FF4E2E0ECCCE3B384084825EC1685D9336589F001A09024F2A85A062857D31448D9B0BAED48B0FA0F0030C0C4DBC4D0EBB5A2D9DF86CD400\n"
+":4002400036841CD6E10383CA5C1DB5D42371D6028120704E0071EF62E85A64412B8C11D90F8BA9DAD70F403467043A9DA9BE75708B0582B71D60160E851B9EC00225FA9D5F\n"
+":40028000508D0397A9DA481B0F0B53010C3CE060753B388188000D81046C1665EA4CA3AE00EA6F911024E5832098120B4103BCA98418340D6F1DA90F53B1BCB1AB2B26B0B8\n"
+":4002C000BE81A64202468195B0F09753B2ADB0F29753B38F528B8B0622BF53B29573010C719CE4000BEBC111F0DF38845B0F71753AA225DA50E5D4EA4248840070ED58A193\n"
+":40030000ADD61C1C6176D016DD4EA6901C3145221DB89689168B168F0045A022C42203D00924B420191CA4223A9920B581622D0DE1A31EC5521EA7504315108A10E8F53A8E\n"
+":4003400081441026A40420C047B7B4C5805826EA746202D3D81C47D07E83E1DBF2097DA633209E702185DD4E843AD631C24E07DE41C882A0E8D8500883A985D4E927EA0A52\n"
+":4003800091640D1FA46838F3C17963D0C4061581A33461F53A422C352913023044E51EA747418EA7451EA743203C4F254C2EA7E12EA69C1EA7451F667F0880E01228F75E61\n"
+":4003C000D8851D41508F58C7884DC8B9E4F00E4D41AB60E621949935069BA922F7B835068ED1AC921361D928911993F16DC9047D4AF280006A0C70A350265D193EA579220E\n"
+":40040000E0C808FA96310030BB32065278D4170B61006526A0C0B299085B2C06008BC195125C9970C18F782ABCBBB12CA84016DEAF681C6B9001DDBC00604BD4EFA7D4F021\n"
+":40044000E2C4103028A1E2A8212D3BFC84AF1E1E86BB301C0BEA71840801CBC67A220519202986071FA5011E3C8B791AC636103D5CF03D4EEC26C2062753BF224262D61290\n"
+":40048000A081113A9DFD101112D11990C25FD248028850804F34031D64A0C1A0277862584C43402FEFC532F292A09086805CD087D5BBA3D4F0425818813F53B5A3D3A7C3F1\n"
+":4004C000A83518521F90EF9CE160663FBC7034220753BC21D62E043303C12753C823103E17AC2363A9AC0BB8808423F0BF61D1A1F24B49ECD64389D028F80E24D1C362C232\n"
+":40050000C55805D68D207A9DD48C034016D12391B23D04C078486B67CE89814A88F0093A9D816EADDC2EA7624BA9D79214BA6B10B0D90F29781EA658200051EC1DE2C3A891\n"
+":4005400022979A760824E42345712087951C22158F898AEA0EDB5712045AEB2541212A487A9E6898D8B34AA50C5947664C10C10EA89710C084F4F8F90E0405B00BA9E0CAAE\n"
+":40058000A7C0B6113A9E153D6840DCF0211F53C4956A956617586E975C36904A6100225F6FEC0E4CF085E4ADA04B64CB2DA300BA9E0D4F4E2A0B8829DC59647B023E69CA48\n"
+":4005C0002C9CB224020E99EA1B8CC881B840BDD1D8226F53B48C84405388FF324D618B524826002F8BCCADA23CBABCADA616E3263CBAC4354424074F080934780343017471\n"
+":4006000005753BC2040174990126123CBF6009552017906824D1CAD881A0C82095C3957E10F206D002EBFFE1F4C6B8F36FC1F04840EB4A47B9BAA4B3F239A19A021D122D49\n"
+":40064000F4B6444F232B965320DCAE65C1D8021B5ED1601EA75B1D8DB4BA9DA46A5C5DBBDC8C7D758457DC09756CA2EA76852E3930480430A9687A9E00C0AF4FBB1803B158\n"
+":40068000DF97595096CA9240490D292F230F8819B1EF8D8B846527C9FEA732200757D6664972010136FF327C202E32FC0799ED0F825746425ADD81CD13190188CAC3CB3A61\n"
+":4006C000EE2985309958726A10B3019AD79C1FE77B362C1EAA801144A768C4EA74D7900018DE608F53A6243EE97C92008990AF3FE8FC2EF638CD8079F44D38EB7D07804C80\n"
+":4007000017893B4A100EF3F0A0083A438CBB3EF0471EDC6211C7D01FA3204420520084509BC554E3CA560C6BE9EB420242409841000F5F36A7186415F38B3137C043546622\n"
+":4007400035866294E005BAF3B10EB1AD508F0090F0509885DD503E208F58D889228C84C890058843F19940F6E0F8FA0FE47AC6C4C24F1F382200B6060E576E875D7E883262\n"
+":40078000680A714304001380BC1321D63664C09C909C800FAC6CD6030428E1018AEEB1B4400D4CD0113AC6CD901BD5FF0671029DBA982009C369503A483EB1B311DE821DA4\n"
+":4007C0000220551020E320491EBDC410089110CB100CB1108D10D7CC74C5D93F22209A219F958BC4412C710289E26FF9C5510978775E08817E30D44FCD3F64207A501CBC4A\n"
+":40080000E7A24790793F86082035424E4CAA3CE7304011D0B5038D109EE478028BA053DD404205909DCE302181E00BF7FBE9819A2D1110BDD60020E1360A034514188200CA\n"
+":40084000D12490308BB5A181E02F2E088D6EF89C8400084A81C049AA4079F9306243CDAA681FFD5B649F65C008244B017D25B02059E0020137BA080202857D6178444751A4\n"
+":40088000C221B8DF161B20B9810EA78649B144A847C6F0440EF5FE01DCA02800030000FC00000000420607DC3800000370001FBF65D648086A09981A74B4D2186D202F46B4\n"
+":4008C0005062BFB838A58537688636074436034ADA4EBE4F64FC797DB6CB25AEC148AE1D6768235B4A620060040100F3545BBA00102FBFB2E4030041100C020480300F9589\n"
+":4009000040C811B8144DCA80016A248B6DB4B007A5E6080F00FA83F87B62F640105B0AC002E02007D0F3C2098060201C010080480202008C6C996F2FBF7EFDFBF7EFDFBF82\n"
+":400940007EFDFBF620601974D400E06010060160601B868E4110339B200D6245D64167F002004F32D54812040140581DD20A1209EF1CA20A8200B0220B8240C6B04A76070B\n"
+":40098000F797DFBF7EC400003618E5F27130B09001E026C0C2D2000006000008000100020300015400000000FFFFA00038000001EC0024A027A019A3BD9B65A21C00195011\n"
+":4009C0000E51EA7F2A07980E101A1029C58F42E18C1085680AF24109F4EFF60530132029205A476124CC308253688BA80E68116621E64072C07C80E282890324F221A41056\n"
+":400A0000C680F47F9FB2F10BE6510B1008D00448440C4009DDE44F063105B84C4FD13513812C6444C7A6C60CFE4BD42A031827DA07CC109FB0C206C708047F9FB8180C0E1D\n"
+":400A40003FCFCA223B075CB01420101FE77632DC4025000B26CB6D091AD9F3267F707F846028FD8B4D93FA4A843BC91F53C0B733AF95B7E80388A750061D500605B00928EF\n"
+":400A800075806DA7964E30040D60DF00431004DC0107D008980045663CF2E12C166008A201146009EA8004815D00A204B000F10084CE1EEA267EAB66EB440CF004CB006E90\n"
+":400AC0005503E4001B6B846CAE07C00405746BE48DAC194001388182008CE01194021200105A00E14700D40115002078041ED000000000000300071C00000000FFFFB54CE5\n"
+":400B00003800000BB031842E00EB34324D91085237306A54416110A68DE000A30205154008530807A3D491F1D47096A267985D44260B0260CC400B0138430CC204612188EC\n"
+":400B4000296631E48200810230721984D1120C8591201304110D5BFF09D88FC40FF48842882D85024CC318449F870AD0E27D236444F096910124C8138B54630EF1FA60064F\n"
+":400B800047060C03C01E107802229000E244096444401801CD0020CA0288C0449431845A6058CA86990D2311145108235003CA0C516063630C021ACED350926C88628834D8\n"
+":400BC000171C18C880230A0A3C7042288450C1418A389A0D30A95442A1B619BA9210A640052024219041919120200EA70D80E31FA1315BA2288950662650E23F68C22708AE\n"
+":400C0000082911C000105A9045A9150224946B3CCA8858268B528A044AA9A0B4301470804290FD16259205D44ABC053A58308B53293C3CB53D00A63C00E1980866528299B5\n"
+":400C4000C0FE200036B039854A8636911EAAA903F921543A03BC2EB22E186FAE9308885A9A408198089D70224CC6326A2A4C006A01872020341D280E1DCD1A46916A6A0208\n"
+":400C8000C52807BD8789080302C43C209980D4608E157E789C68033980406580105412005DA9C8629912B6A86100AA4D0AA321506600B19F8133D44B5216EAD2F0600CD578\n"
+":400CC000E9D811ABE6B0519B4B986312614240623569D26308F4183229183A44714FCEF7A25B9985B9A45B9B05B9BC5B9C85B9D45B9E048B802C5060E413FC050801628340\n"
+":400D0000A12E6404014552100528F127C97010001D84983D8B4130A34183C7FC52C626C8344022E0212039ED88C1860418EE45598D102451405E961B0420136083062BA004\n"
+":400D400061081A0744C2200C8D30288402164210D230C03833BBE00568430300540840101A206A44ACB611A850400688214016143B9E745806A65462408150301008B002FF\n"
+":400D8000DA4880085003A63195A339B14AC67F11C0040D8662200D972512808C33200242A013214992B312838EFAC2389F426F0B7FA00144A4C494C05A346070E0070041CC\n"
+":400DC000ED4910264C834334804D2B9048C6CB7390384C05CCC89110C70048FC33604AC10993290040D0828EBC1818A12A148A86770F19B104182E0192E024AD3231848E63\n"
+":400E0000C50D1DBA1EED9E862DAA364481410EDC2110301D0641AE6CF62099CC088320596648E0104899C93D133C1118540EB034B550C680CC052A00231540328866A04975\n"
+":400E4000EBE007C92AC092A00929B89EB4846040EA038DC029FBC17024D13FC183ECF492B171E15334CC8C8322058901C4CC3FE2CFBF55C8D5C7FB004583470BE4D8A02C37\n"
+":400E80001A11A0C1A11E38D30640A05E0BA522034118B890958B4C800426811408C004190043388548ECACE26C0EB394B47A00C330072054B93C801BD1401E6E20C022E55F\n"
+":400EC000809804870AB02BCA02D820299A08C8422828C215860C8A6725EF226657191FB6F2314CC6C9B62884EEDA0310280023D532968C8627F5D747CAA208F0883CA151BD\n"
+":400F00008F205810B080E2F719F868289EC60199720A4CB1BBAC09727C45050E50523B10054B93E8BA092C7442A1400586739A13610A85422082850A7220D3356401400236\n"
+":400F4000110022AD7511237F049E6329E0251FE139F41F1B65B802631EC669E44C1F8501FC379C0771F0589F4689EC5C9FC39800311DA7C1F25B9F4231EE639F43D80006C6\n"
+":400F80001E2411F0029F24B1F0149F0730004D9E4339EE32CAC0F8064F815C00040F2398F2220F734E340F638BCDF022425C28F22288BC8BF540CA2ECD62EFCB0BE25D9FF9\n"
+":400FC00045E00C5E592072099485200D300EB38C4CB0308043896C040030EA97008004AC5D040025A1881419990883360031C03EDCB1A400895C40DEA9E5E44201406913D8\n"
+":40100000222010801C8B1B8758F5D108044DE40B10098E02B0500791003C42E0F43AA2801804AB0A5A50717515146DA26C86575C8CF076D947C79EF3D0974200452E14293F\n"
+":40104000084B95986C081FF0EA870A34F028C8C380CC0A010AC340A0102044582A19D293EDC2A1EDA699026E134A99194828816022112B94C030053C21106C950030212091\n"
+":4010800054434074CBFE23C0009D1005533D00387011450400F4022734EA40F30C00A381EC080400C735CA996A1160D4DA0790D61E84B12B8E3D065A2043C0E07F0300607C\n"
+":4010C0000CA542113E3562C312C1F40C81E03AC9F84C90033269EA638804055422A3880810230EA01018472C0504000CCA857D203880C0C8661B3952E2600C02014560382D\n"
+":4011000000A40C6718D3C0E209010D4A50076D982C0280843AC0B5375220586018043D12F0312A8863884597CC266600C2AE34CAE344688757CF4832EC5906804AB168015C\n"
+":40114000C72C5B1A213AB792A725C6821305549528732B001005D8BA2B02AA8958702F001E8266171B1C997C0ED8AD1B2894C02220E06001E2E0107A80A0F00223CB0A2DF1\n"
+":401180001B0A018574F1450CB469705D0E32D03298ADB60C4202F5A68C600CD7F57ABC88F38326461B692CF5F4F2065662781AC0CECEF72C1C04381A567264D6DBAEE9E038\n"
+":4011C000E242DA10F2752000D69A12B2C1B20387908E64BC120BC14A652030B3F4A720DE6E53E0029E6837133188200F6F8E22E4C82D810142FE9183228F369C588A12E8BA\n"
+":40120000508202ECC844BC08142E5D3428000000050001EC00000000000001E071BE00A854AB0003A000A0C4A188522F0010E6FAE7CFED9AF9E000000574074B0F6015AEC6\n"
+":40124000165A17531635155C13EF13991266515C0001003ED44071C60100607B0011000000300060009000C000F001200150018001B001E002100240027002A002D00300FC\n"
+":40128000605D000200009C4053BF00020199033370F4000070710002FF86FF8670760F33549AFEAE53B4005F5058118053E900021000100054B4000C544E002850340580B8\n"
+":4012C000501A01005010F8805018FDCD53510008F000080000001000F8000266F0000333534A8000537D00020000000053610008C0004000C0004000C0004000C000400094\n"
+":40130000526F00080000000000000000000000000000000002990002F4F901535376F7F55348C0005100115F7151002000400040004000400040004000400040FA41FC4CD0\n"
+":4013400001520453074F0748044200400040F842F749F94DFC50FE500050064B0B400B4300400040004000400040004071B2522C52AA014052B30002080000A0512E200018\n"
+":40138000512C010053840000539E01E0539C099952A300020000000052D2008052E50003004003000400533E6000538D00020000823552E1000200001000533E5000531E38\n"
+":4013C0000C00546B000708000CCC0E660E660B330B331000545600E6545A1000545F00040700157C04000FA054680000545C00A060110003B57CB9B8C0D4000000000000C1\n"
+":401400004953505468726561644C6F6F70006170313330325F7365745F6374726C00000020257328256429204572726F72204F6363757272656420696E2048414C5F49329F\n"
+":40144000435F536C617665527843706C7443616C6C6261636B2020537461747573203D203078253032782C20675F736C6176655F6E6578745F72785F6C656E203D20257534\n"
+":4014800020200A0D0000000020257328256429204572726F72204F6363757272656420696E2048414C5F4932435F536C617665547843706C7443616C6C6261636B20207340\n"
+":4014C0007461747573203D2030782530327820675F736C6176655F6E6578745F72785F6C656E203D202575200A0D000025732825642920446562756720496E6974696174D8\n"
+":401500006564205359534346475F4346475231203D203078253038782020464C4153482D3E4F505452203D20307825303878200A0D00000049535054687265616400000014\n"
+":4015400064656661756C745461736B00496E76616C696420466F726D6174202D2030782530387820213D20307825303878202C20205769647468202D2025687520213D20A5\n"
+":40158000256875202C20486569676874202D2025687520213D20256875200A0D000000000A0D2052454144204D4173746572205472616E736D6974204572726F7220212161\n"
+":4015C00020202D20307825303278203078253038782020524547203D2030782530347820666F7220736C61766520307825303278200A0D000A0D205752495445204D417323\n"
+":40160000746572205472616E736D6974204572726F7220212120202D203078253032782030782530387820524547203D2030782530347820666F7220736C617665203078D2\n"
+":4016400025303278200A0D000A0D204D41737465722052656365697665204572726F72202121202D203078253032782030782530387820666F7220736C61766520307825D2\n"
+":401680003032782020666F7220524547202D20307825303478200A0D00000000BC16020800000020A80000006A4A000864170208A8000020383100007A4A000880841E007A\n"
+":4016C00000000000AAAAAAAA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042\n"
+":401700000000000000000000000000000000000000000000000000000000000000000005FFFF0000000000000000000000000000C0FF0208000000000000000000000000DD\n"
+":2417400000000000000000000000000000000000000000000000000000000000000000000000000085\n"
+":020000040800F2\n"
+":4000000008040020D5000008C9010008C701000800000000000000000000000000000000000000000000000000000000CD0100080000000000000000CB010008CF01000893\n"
+":40004000E7000008E7000008E7000008E7000008E7000008E7000008E7000008E700000800000000E7000008E7000008E7000008E7000008E7000008E7000008E70000087F\n"
+":40008000E7000008E7000008E700000800000000E7000008E7000008E7000008E7000008E7000008E7000008E7000008E7000008E7000008E700000800000000000000001D\n"
+":4000C0000348854600F014F80048004751020008080400200448804704480047FEE7FEE7FEE7FEE7FEE7FEE7DD010008C1000008064C0125064E05E0E36807CC2B430C3CA0\n"
+":4001000098471034B442F7D3FFF7DEFFA4020008C402000810B500210748C9438162002282624162426201620262C161C26100F00DF8002010BD0000001002400248016829\n"
+":40014000491C016070470000000000207047000008B515480168821511430160C16889088900C1600168114A114001600168012212041140009101689200914301600021AD\n"
+":40018000C16042680A4B1A4005235B03D218426042681F231B029A438314D2184260016105490448086008BD00100240D4FFF6FEFF1FFF0068FF1F0004000020704710B525\n"
+":4001C000FFF7FCFF10BDFEE770477047704710B5FFF7B4FFFFF7F3FF10BD000010480168821511430160C1680E4A1140C16001680D4A1140016081684908490081600168D5\n"
+":400200000122920491430160C168FD2212049143C160002101610549C003886070470000001002400C40FF88F6FFF6FE00ED00E002E008C8121F08C1002AFAD17047704760\n"
+":40024000002001E001C1121F002AFBD17047000008B5002462B60F48009401680E4A1140C204914214D1416800910D46016881F3088872B609498860FFF76AFF08480461F9\n"
+":4002800044618461012080F31088FFF743FFA847FEE70000000400080000FE2F00ED00E000E000E0C4020008000000200800000030020008CC020008080000200004000084\n"
+":0C02C000400200080000000080841E00C6\n"
+":020000040802F0\n"
+":20FFC0003131353043553936524b56313930313131306433383138393458585858585858f6\n"
+":04000005080000C12E\n"
+":00000001FF\n"
diff --git a/drivers/media/platform/imx8/mcu_firmware.h b/drivers/media/platform/imx8/mcu_firmware.h
new file mode 100644
index 000000000000..de06baedd10f
--- /dev/null
+++ b/drivers/media/platform/imx8/mcu_firmware.h
@@ -0,0 +1,91 @@
+#ifndef _MCU_FIRMWARE_H
+#define _MCU_FIRMWARE_H
+
+/* Local Defines */
+#define MAX_BUF_LEN 2048
+
+#define MAX_PAGES 512
+#define TOTAL_PAGES 1536
+#define NUM_ERASE_CYCLES (TOTAL_PAGES / MAX_PAGES)
+
+#define FLASH_START_ADDRESS 0x08000000
+#define FLASH_SIZE 192*1024
+#define FLASH_READ_LEN 256
+
+#define CR 13 /* Carriage return */
+#define LF 10 /* Line feed */
+
+/*MCU Buffer size increased - Fix for loading menu based controls */
+#define MCU_BUFFER_SIZE 1024
+
+/* TODO: Only necessary commands added */
+enum _i2c_cmds
+{
+ BL_GET_VERSION = 0x01,
+ BL_GO = 0x21,
+ BL_READ_MEM = 0x11,
+ BL_WRITE_MEM = 0x31,
+ BL_WRITE_MEM_NS = 0x32,
+ BL_ERASE_MEM = 0x44,
+ BL_ERASE_MEM_NS = 0x45,
+};
+
+enum _i2c_resp
+{
+ RESP_ACK = 0x79,
+ RESP_NACK = 0x1F,
+ RESP_BUSY = 0x76,
+};
+
+enum
+{
+ NUM_LANES_1 = 0x01,
+ NUM_LANES_2 = 0x02,
+ NUM_LANES_3 = 0x03,
+ NUM_LANES_4 = 0x04,
+ NUM_LANES_UNKWN = 0xFF,
+};
+
+enum _ihex_rectype
+{
+ /* Normal data */
+ REC_TYPE_DATA = 0x00,
+ /* End of File */
+ REC_TYPE_EOF = 0x01,
+
+ /* Extended Segment Address */
+ REC_TYPE_ESA = 0x02,
+ /* Start Segment Address */
+ REC_TYPE_SSA = 0x03,
+
+ /* Extended Linear Address */
+ REC_TYPE_ELA = 0x04,
+ /* Start Linear Address */
+ REC_TYPE_SLA = 0x05,
+};
+
+typedef struct __attribute__ ((packed)) _ihex_rec {
+ unsigned char datasize;
+ unsigned short int addr;
+ unsigned char rectype;
+ unsigned char recdata[];
+} IHEX_RECORD;
+
+unsigned int g_bload_flashaddr = 0x0000;
+
+uint8_t *fw_version = NULL;
+
+/* MCU communication variables */
+unsigned char mc_data[MCU_BUFFER_SIZE];
+unsigned char mc_ret_data[MCU_BUFFER_SIZE];
+
+/* Buffer to Send Bootloader CMDs */
+unsigned char g_bload_buf[MAX_BUF_LEN] = { 0 };
+
+unsigned short int g_bload_crc16 = 0x0000;
+
+const char g_mcu_fw_buf[] =
+#include "ecam50_cam_fw.txt"
+ ;
+
+#endif //_MCU_FIRMWARE_H
diff --git a/drivers/media/platform/imx8/mcu_firmware_1335.h b/drivers/media/platform/imx8/mcu_firmware_1335.h
new file mode 100644
index 000000000000..9c12ff3c4155
--- /dev/null
+++ b/drivers/media/platform/imx8/mcu_firmware_1335.h
@@ -0,0 +1,91 @@
+#ifndef _MCU_FIRMWARE_H
+#define _MCU_FIRMWARE_H
+
+/* Local Defines */
+#define MAX_BUF_LEN 2048
+
+#define MAX_PAGES 512
+#define TOTAL_PAGES 1536
+#define NUM_ERASE_CYCLES (TOTAL_PAGES / MAX_PAGES)
+
+#define FLASH_START_ADDRESS 0x08000000
+#define FLASH_SIZE 192*1024
+#define FLASH_READ_LEN 256
+
+#define CR 13 /* Carriage return */
+#define LF 10 /* Line feed */
+
+/*MCU Buffer size increased - Fix for loading menu based controls */
+#define MCU_BUFFER_SIZE 1024
+
+/* TODO: Only necessary commands added */
+enum _i2c_cmds
+{
+ BL_GET_VERSION = 0x01,
+ BL_GO = 0x21,
+ BL_READ_MEM = 0x11,
+ BL_WRITE_MEM = 0x31,
+ BL_WRITE_MEM_NS = 0x32,
+ BL_ERASE_MEM = 0x44,
+ BL_ERASE_MEM_NS = 0x45,
+};
+
+enum _i2c_resp
+{
+ RESP_ACK = 0x79,
+ RESP_NACK = 0x1F,
+ RESP_BUSY = 0x76,
+};
+
+enum
+{
+ NUM_LANES_1 = 0x01,
+ NUM_LANES_2 = 0x02,
+ NUM_LANES_3 = 0x03,
+ NUM_LANES_4 = 0x04,
+ NUM_LANES_UNKWN = 0xFF,
+};
+
+enum _ihex_rectype
+{
+ /* Normal data */
+ REC_TYPE_DATA = 0x00,
+ /* End of File */
+ REC_TYPE_EOF = 0x01,
+
+ /* Extended Segment Address */
+ REC_TYPE_ESA = 0x02,
+ /* Start Segment Address */
+ REC_TYPE_SSA = 0x03,
+
+ /* Extended Linear Address */
+ REC_TYPE_ELA = 0x04,
+ /* Start Linear Address */
+ REC_TYPE_SLA = 0x05,
+};
+
+typedef struct __attribute__ ((packed)) _ihex_rec {
+ unsigned char datasize;
+ unsigned short int addr;
+ unsigned char rectype;
+ unsigned char recdata[];
+} IHEX_RECORD;
+
+unsigned int g_bload_flashaddr_1335 = 0x0000;
+
+uint8_t *fw_version_1335 = NULL;
+
+/* MCU communication variables */
+unsigned char mc_data_1335[MCU_BUFFER_SIZE];
+unsigned char mc_ret_data_1335[MCU_BUFFER_SIZE];
+
+/* Buffer to Send Bootloader CMDs */
+unsigned char g_bload_buf_1335[MAX_BUF_LEN] = { 0 };
+
+unsigned short int g_bload_crc16_1335 = 0x0000;
+
+const char g_mcu_fw_buf_1335[] =
+#include "ecam131_mcu_fw.txt"
+ ;
+
+#endif //_MCU_FIRMWARE_H
diff --git a/drivers/media/platform/mxc/capture/Kconfig b/drivers/media/platform/mxc/capture/Kconfig
index 040f410ff2d4..471afd676a65 100644
--- a/drivers/media/platform/mxc/capture/Kconfig
+++ b/drivers/media/platform/mxc/capture/Kconfig
@@ -61,12 +61,26 @@ config MXC_CAMERA_OV5640_MIPI_V2
help
If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+config MXC_CAMERA_OV5640_MIPI_NV
+ tristate "OmniVision ov5640 camera support using mipi (based on driver from nVidia)"
+ depends on MXC_MIPI_CSI && I2C
+ ---help---
+ If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+
config MXC_CAMERA_OV5647_MIPI
tristate "OmniVision ov5647 camera support using mipi"
depends on MXC_MIPI_CSI && I2C
help
If you plan to use the ov5647 Camera with mipi interface in your MXC system, say Y here.
+config MXC_HDMI_CSI2_TC358743
+ tristate "Toshiba tc358743 Hdmi to CSI 2 bridge"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ select MXC_MIPI_CSI2 if ARCH_MX6Q
+ select MXC_CAMERA_SENSOR_CLK
+ ---help---
+ Toshina HDMI to MIPI-CSI2 bridge
+
config MXC_TVIN_ADV7180
tristate "Analog Device adv7180 TV Decoder Input support"
depends on !VIDEO_MXC_EMMA_CAMERA && I2C
@@ -74,6 +88,20 @@ config MXC_TVIN_ADV7180
help
If you plan to use the adv7180 video decoder with your MXC system, say Y here.
+config MXC_TVIN_ADV7280
+ tristate "Analog Device adv7280 TV Decoder Input support"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ select VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the adv7280 video decoder with your MXC system, say Y here.
+
+config MXC_TVIN_MAX9526
+ tristate "Maxim Integrated MAX9526 NTSC/PAL Decoder Input support"
+ depends on !VIDEO_MXC_EMMA_CAMERA && I2C
+ select VIDEO_V4L2_MXC_INT_DEVICE
+ ---help---
+ If you plan to use the MAX9526 video decoder with your MXC system, say Y here.
+
choice
prompt "Select Overlay Rounting"
default MXC_IPU_DEVICE_QUEUE_SDC
diff --git a/drivers/media/platform/mxc/capture/Makefile b/drivers/media/platform/mxc/capture/Makefile
index e6e4b99f9435..1abe623d4048 100644
--- a/drivers/media/platform/mxc/capture/Makefile
+++ b/drivers/media/platform/mxc/capture/Makefile
@@ -29,10 +29,22 @@ obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi_int.o
ov5640_camera_mipi_v2-objs := ov5640_mipi_v2.o
obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI_V2) += ov5640_camera_mipi_v2.o
+ov5640_camera_mipi_nv-objs := ov5640_mipi_nv.o
+obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI_NV) += ov5640_camera_mipi_nv.o
+
ov5647_camera_mipi-objs := ov5647_mipi.o
obj-$(CONFIG_MXC_CAMERA_OV5647_MIPI) += ov5647_camera_mipi.o
+tc358743_h2c_bridge-objs := tc358743_h2c.o
+obj-$(CONFIG_MXC_HDMI_CSI2_TC358743) += tc358743_h2c_bridge.o
+
adv7180_tvin-objs := adv7180.o
obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
+adv7280_tvin-objs := adv7280.o
+obj-$(CONFIG_MXC_TVIN_ADV7280) += adv7280_tvin.o
+
+max9526_tvin-objs := max9526.o
+obj-$(CONFIG_MXC_TVIN_MAX9526) += max9526_tvin.o
+
obj-$(CONFIG_VIDEO_V4L2_MXC_INT_DEVICE) += v4l2-int-device.o
diff --git a/drivers/media/platform/mxc/capture/adv7180.c b/drivers/media/platform/mxc/capture/adv7180.c
index ff75823021b1..8171c1729232 100644
--- a/drivers/media/platform/mxc/capture/adv7180.c
+++ b/drivers/media/platform/mxc/capture/adv7180.c
@@ -34,6 +34,13 @@
#include "v4l2-int-device.h"
#include "mxc_v4l2_capture.h"
+#if 0
+#undef dev_dbg
+#define dev_dbg(dev, format, arg...) {dev_printk(KERN_ERR, dev, format, ##arg);}
+#undef pr_debug
+#define pr_debug(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#endif
+
#define ADV7180_VOLTAGE_ANALOG 1800000
#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
@@ -85,6 +92,7 @@ static struct i2c_driver adv7180_i2c_driver = {
struct sensor {
struct sensor_data sen;
v4l2_std_id std_id;
+ int rev_id;
} adv7180_data;
@@ -195,8 +203,10 @@ static struct v4l2_queryctrl adv7180_qctrl[] = {
static inline void adv7180_power_down(int enable)
{
- gpio_set_value_cansleep(pwn_gpio, !enable);
- msleep(2);
+ if (gpio_is_valid(pwn_gpio)) {
+ gpio_set_value_cansleep(pwn_gpio, !enable);
+ msleep(2);
+ }
}
static int adv7180_regulator_enable(struct device *dev)
@@ -292,6 +302,9 @@ static inline int adv7180_read(u8 reg)
"%s:read reg error: reg=%2x\n", __func__, reg);
return -1;
}
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:read reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
return val;
}
@@ -305,6 +318,8 @@ static int adv7180_write_reg(u8 reg, u8 val)
{
s32 ret;
+ dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ "%s:write reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
if (ret < 0) {
dev_dbg(&adv7180_data.sen.i2c_client->dev,
@@ -392,10 +407,16 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
/* Initialize structure to 0s then set any non-0 values. */
memset(p, 0, sizeof(*p));
p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
+#if 0
p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
p->u.bt656.nobt_hs_inv = 1;
p->u.bt656.bt_sync_correct = 1;
-
+#else
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 0;
+ p->u.bt656.bt_sync_correct = 0;
+ p->u.bt656.clock_curr = 0; //BT656 interlace clock mode
+#endif
/* ADV7180 has a dedicated clock so no clock settings needed. */
return 0;
@@ -429,13 +450,13 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
* This is a workaround for preview scrolling issue.
*/
msleep(400);
+
} else if (!on && sensor->sen.on) {
if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
return -EIO;
}
sensor->sen.on = on;
-
return 0;
}
@@ -938,8 +959,8 @@ static void adv7180_hard_reset(bool cvbs)
"In adv7180:adv7180_hard_reset\n");
if (cvbs) {
- /* Set CVBS input on AIN1 */
- adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
+ /* Set CVBS input on AIN4 */
+ adv7180_write_reg(ADV7180_INPUT_CTL, 0x03);
} else {
/*
* Set YPbPr input on AIN1,4,5 and normal
@@ -948,13 +969,12 @@ static void adv7180_hard_reset(bool cvbs)
adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
}
- /* Datasheet recommends */
+/* The used chip on the Toradex ACM module reacts badly to writes to
+ nonexisting/reserved/read only registers, so reduce the above list to the
+ writable ones in the datasheet sheet */
adv7180_write_reg(0x01, 0xc8);
- adv7180_write_reg(0x02, 0x04);
- adv7180_write_reg(0x03, 0x00);
+ adv7180_write_reg(0x03, 0x0C);
adv7180_write_reg(0x04, 0x45);
- adv7180_write_reg(0x05, 0x00);
- adv7180_write_reg(0x06, 0x02);
adv7180_write_reg(0x07, 0x7F);
adv7180_write_reg(0x08, 0x80);
adv7180_write_reg(0x0A, 0x00);
@@ -962,31 +982,15 @@ static void adv7180_hard_reset(bool cvbs)
adv7180_write_reg(0x0C, 0x36);
adv7180_write_reg(0x0D, 0x7C);
adv7180_write_reg(0x0E, 0x00);
- adv7180_write_reg(0x0F, 0x00);
- adv7180_write_reg(0x13, 0x00);
+ adv7180_write_reg(0x0F, 0x04);//00
+ adv7180_write_reg(0x13, 0x00);//R
adv7180_write_reg(0x14, 0x12);
adv7180_write_reg(0x15, 0x00);
- adv7180_write_reg(0x16, 0x00);
adv7180_write_reg(0x17, 0x01);
adv7180_write_reg(0x18, 0x93);
- adv7180_write_reg(0xF1, 0x19);
- adv7180_write_reg(0x1A, 0x00);
- adv7180_write_reg(0x1B, 0x00);
- adv7180_write_reg(0x1C, 0x00);
+ adv7180_write_reg(0x19, 0xF1);
adv7180_write_reg(0x1D, 0x40);
- adv7180_write_reg(0x1E, 0x00);
- adv7180_write_reg(0x1F, 0x00);
- adv7180_write_reg(0x20, 0x00);
- adv7180_write_reg(0x21, 0x00);
- adv7180_write_reg(0x22, 0x00);
- adv7180_write_reg(0x23, 0xC0);
- adv7180_write_reg(0x24, 0x00);
- adv7180_write_reg(0x25, 0x00);
- adv7180_write_reg(0x26, 0x00);
adv7180_write_reg(0x27, 0x58);
- adv7180_write_reg(0x28, 0x00);
- adv7180_write_reg(0x29, 0x00);
- adv7180_write_reg(0x2A, 0x00);
adv7180_write_reg(0x2B, 0xE1);
adv7180_write_reg(0x2C, 0xAE);
adv7180_write_reg(0x2D, 0xF4);
@@ -1003,18 +1007,8 @@ static void adv7180_hard_reset(bool cvbs)
adv7180_write_reg(0x38, 0x80);
adv7180_write_reg(0x39, 0xC0);
adv7180_write_reg(0x3A, 0x10);
- adv7180_write_reg(0x3B, 0x05);
- adv7180_write_reg(0x3C, 0x58);
adv7180_write_reg(0x3D, 0xB2);
- adv7180_write_reg(0x3E, 0x64);
- adv7180_write_reg(0x3F, 0xE4);
- adv7180_write_reg(0x40, 0x90);
adv7180_write_reg(0x41, 0x01);
- adv7180_write_reg(0x42, 0x7E);
- adv7180_write_reg(0x43, 0xA4);
- adv7180_write_reg(0x44, 0xFF);
- adv7180_write_reg(0x45, 0xB6);
- adv7180_write_reg(0x46, 0x12);
adv7180_write_reg(0x48, 0x00);
adv7180_write_reg(0x49, 0x00);
adv7180_write_reg(0x4A, 0x00);
@@ -1022,171 +1016,34 @@ static void adv7180_hard_reset(bool cvbs)
adv7180_write_reg(0x4C, 0x00);
adv7180_write_reg(0x4D, 0xEF);
adv7180_write_reg(0x4E, 0x08);
- adv7180_write_reg(0x4F, 0x08);
adv7180_write_reg(0x50, 0x08);
adv7180_write_reg(0x51, 0x24);
- adv7180_write_reg(0x52, 0x0B);
- adv7180_write_reg(0x53, 0x4E);
- adv7180_write_reg(0x54, 0x80);
- adv7180_write_reg(0x55, 0x00);
- adv7180_write_reg(0x56, 0x10);
- adv7180_write_reg(0x57, 0x00);
adv7180_write_reg(0x58, 0x00);
adv7180_write_reg(0x59, 0x00);
- adv7180_write_reg(0x5A, 0x00);
- adv7180_write_reg(0x5B, 0x00);
- adv7180_write_reg(0x5C, 0x00);
- adv7180_write_reg(0x5D, 0x00);
- adv7180_write_reg(0x5E, 0x00);
- adv7180_write_reg(0x5F, 0x00);
- adv7180_write_reg(0x60, 0x00);
- adv7180_write_reg(0x61, 0x00);
- adv7180_write_reg(0x62, 0x20);
- adv7180_write_reg(0x63, 0x00);
- adv7180_write_reg(0x64, 0x00);
- adv7180_write_reg(0x65, 0x00);
- adv7180_write_reg(0x66, 0x00);
- adv7180_write_reg(0x67, 0x03);
- adv7180_write_reg(0x68, 0x01);
- adv7180_write_reg(0x69, 0x00);
- adv7180_write_reg(0x6A, 0x00);
- adv7180_write_reg(0x6B, 0xC0);
- adv7180_write_reg(0x6C, 0x00);
- adv7180_write_reg(0x6D, 0x00);
- adv7180_write_reg(0x6E, 0x00);
- adv7180_write_reg(0x6F, 0x00);
- adv7180_write_reg(0x70, 0x00);
- adv7180_write_reg(0x71, 0x00);
- adv7180_write_reg(0x72, 0x00);
- adv7180_write_reg(0x73, 0x10);
- adv7180_write_reg(0x74, 0x04);
- adv7180_write_reg(0x75, 0x01);
- adv7180_write_reg(0x76, 0x00);
- adv7180_write_reg(0x77, 0x3F);
- adv7180_write_reg(0x78, 0xFF);
- adv7180_write_reg(0x79, 0xFF);
- adv7180_write_reg(0x7A, 0xFF);
- adv7180_write_reg(0x7B, 0x1E);
- adv7180_write_reg(0x7C, 0xC0);
- adv7180_write_reg(0x7D, 0x00);
- adv7180_write_reg(0x7E, 0x00);
- adv7180_write_reg(0x7F, 0x00);
- adv7180_write_reg(0x80, 0x00);
- adv7180_write_reg(0x81, 0xC0);
- adv7180_write_reg(0x82, 0x04);
- adv7180_write_reg(0x83, 0x00);
- adv7180_write_reg(0x84, 0x0C);
- adv7180_write_reg(0x85, 0x02);
- adv7180_write_reg(0x86, 0x03);
- adv7180_write_reg(0x87, 0x63);
- adv7180_write_reg(0x88, 0x5A);
- adv7180_write_reg(0x89, 0x08);
- adv7180_write_reg(0x8A, 0x10);
- adv7180_write_reg(0x8B, 0x00);
- adv7180_write_reg(0x8C, 0x40);
- adv7180_write_reg(0x8D, 0x00);
- adv7180_write_reg(0x8E, 0x40);
adv7180_write_reg(0x8F, 0x00);
- adv7180_write_reg(0x90, 0x00);
- adv7180_write_reg(0x91, 0x50);
- adv7180_write_reg(0x92, 0x00);
- adv7180_write_reg(0x93, 0x00);
- adv7180_write_reg(0x94, 0x00);
- adv7180_write_reg(0x95, 0x00);
- adv7180_write_reg(0x96, 0x00);
- adv7180_write_reg(0x97, 0xF0);
- adv7180_write_reg(0x98, 0x00);
- adv7180_write_reg(0x99, 0x00);
- adv7180_write_reg(0x9A, 0x00);
- adv7180_write_reg(0x9B, 0x00);
- adv7180_write_reg(0x9C, 0x00);
- adv7180_write_reg(0x9D, 0x00);
- adv7180_write_reg(0x9E, 0x00);
- adv7180_write_reg(0x9F, 0x00);
- adv7180_write_reg(0xA0, 0x00);
- adv7180_write_reg(0xA1, 0x00);
- adv7180_write_reg(0xA2, 0x00);
- adv7180_write_reg(0xA3, 0x00);
- adv7180_write_reg(0xA4, 0x00);
- adv7180_write_reg(0xA5, 0x00);
- adv7180_write_reg(0xA6, 0x00);
- adv7180_write_reg(0xA7, 0x00);
- adv7180_write_reg(0xA8, 0x00);
- adv7180_write_reg(0xA9, 0x00);
- adv7180_write_reg(0xAA, 0x00);
- adv7180_write_reg(0xAB, 0x00);
- adv7180_write_reg(0xAC, 0x00);
- adv7180_write_reg(0xAD, 0x00);
- adv7180_write_reg(0xAE, 0x60);
- adv7180_write_reg(0xAF, 0x00);
- adv7180_write_reg(0xB0, 0x00);
- adv7180_write_reg(0xB1, 0x60);
adv7180_write_reg(0xB2, 0x1C);
- adv7180_write_reg(0xB3, 0x54);
- adv7180_write_reg(0xB4, 0x00);
- adv7180_write_reg(0xB5, 0x00);
- adv7180_write_reg(0xB6, 0x00);
- adv7180_write_reg(0xB7, 0x13);
- adv7180_write_reg(0xB8, 0x03);
- adv7180_write_reg(0xB9, 0x33);
- adv7180_write_reg(0xBF, 0x02);
- adv7180_write_reg(0xC0, 0x00);
- adv7180_write_reg(0xC1, 0x00);
- adv7180_write_reg(0xC2, 0x00);
adv7180_write_reg(0xC3, 0x00);
adv7180_write_reg(0xC4, 0x00);
- adv7180_write_reg(0xC5, 0x81);
- adv7180_write_reg(0xC6, 0x00);
- adv7180_write_reg(0xC7, 0x00);
- adv7180_write_reg(0xC8, 0x00);
- adv7180_write_reg(0xC9, 0x04);
- adv7180_write_reg(0xCC, 0x69);
- adv7180_write_reg(0xCD, 0x00);
- adv7180_write_reg(0xCE, 0x01);
- adv7180_write_reg(0xCF, 0xB4);
- adv7180_write_reg(0xD0, 0x00);
- adv7180_write_reg(0xD1, 0x10);
- adv7180_write_reg(0xD2, 0xFF);
- adv7180_write_reg(0xD3, 0xFF);
- adv7180_write_reg(0xD4, 0x7F);
- adv7180_write_reg(0xD5, 0x7F);
- adv7180_write_reg(0xD6, 0x3E);
- adv7180_write_reg(0xD7, 0x08);
- adv7180_write_reg(0xD8, 0x3C);
- adv7180_write_reg(0xD9, 0x08);
- adv7180_write_reg(0xDA, 0x3C);
- adv7180_write_reg(0xDB, 0x9B);
adv7180_write_reg(0xDC, 0xAC);
adv7180_write_reg(0xDD, 0x4C);
- adv7180_write_reg(0xDE, 0x00);
- adv7180_write_reg(0xDF, 0x00);
- adv7180_write_reg(0xE0, 0x14);
adv7180_write_reg(0xE1, 0x80);
adv7180_write_reg(0xE2, 0x80);
adv7180_write_reg(0xE3, 0x80);
adv7180_write_reg(0xE4, 0x80);
adv7180_write_reg(0xE5, 0x25);
- adv7180_write_reg(0xE6, 0x44);
+ adv7180_write_reg(0xE6, 0x44);//0x04
adv7180_write_reg(0xE7, 0x63);
adv7180_write_reg(0xE8, 0x65);
adv7180_write_reg(0xE9, 0x14);
adv7180_write_reg(0xEA, 0x63);
adv7180_write_reg(0xEB, 0x55);
adv7180_write_reg(0xEC, 0x55);
- adv7180_write_reg(0xEE, 0x00);
- adv7180_write_reg(0xEF, 0x4A);
- adv7180_write_reg(0xF0, 0x44);
- adv7180_write_reg(0xF1, 0x0C);
- adv7180_write_reg(0xF2, 0x32);
adv7180_write_reg(0xF3, 0x00);
- adv7180_write_reg(0xF4, 0x3F);
- adv7180_write_reg(0xF5, 0xE0);
- adv7180_write_reg(0xF6, 0x69);
- adv7180_write_reg(0xF7, 0x10);
+ adv7180_write_reg(0xF4, 0x15);
adv7180_write_reg(0xF8, 0x00);
adv7180_write_reg(0xF9, 0x03);
- adv7180_write_reg(0xFA, 0xFA);
adv7180_write_reg(0xFB, 0x40);
+ adv7180_write_reg(0xFC, 0x04);//was missing
}
/*! ADV7180 I2C attach function.
@@ -1208,13 +1065,12 @@ static void adv7180_hard_reset(bool cvbs)
static int adv7180_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- int rev_id;
int ret = 0;
u32 cvbs = true;
struct pinctrl *pinctrl;
struct device *dev = &client->dev;
- printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
+ dev_dbg(dev, "%s sensor data is at %p\n", __func__, &adv7180_data);
pinctrl = devm_pinctrl_get_select_default(dev);
if (IS_ERR(pinctrl)) {
@@ -1224,15 +1080,15 @@ static int adv7180_probe(struct i2c_client *client,
/* request power down pin */
pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
- if (!gpio_is_valid(pwn_gpio)) {
- dev_err(dev, "no sensor pwdn pin available\n");
- return -ENODEV;
- }
- ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ if (!gpio_is_valid(pwn_gpio))
+ dev_warn(dev, "no sensor pwdn pin available\n");
+ else {
+ ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
"adv7180_pwdn");
- if (ret < 0) {
- dev_err(dev, "no power pin available!\n");
- return ret;
+ if (ret < 0) {
+ dev_err(dev, "no power pin available!\n");
+ //return ret;
+ }
}
adv7180_regulator_enable(dev);
@@ -1282,6 +1138,9 @@ static int adv7180_probe(struct i2c_client *client,
return ret;
}
+ /* ADV7180 is always parallel IF */
+ adv7180_data.sen.mipi_camera = 0;
+
clk_prepare_enable(adv7180_data.sen.sensor_clk);
dev_dbg(&adv7180_data.sen.i2c_client->dev,
@@ -1289,10 +1148,26 @@ static int adv7180_probe(struct i2c_client *client,
__func__, adv7180_data.sen.i2c_client->addr);
/*! Read the revision ID of the tvin chip */
- rev_id = adv7180_read(ADV7180_IDENT);
- dev_dbg(dev,
- "%s:Analog Device adv7%2X0 detected!\n", __func__,
- rev_id);
+ adv7180_data.rev_id = adv7180_read(ADV7180_IDENT);
+ switch(adv7180_data.rev_id) {
+ case 0x1b:
+ case 0x1c:
+ case 0x1e:
+ dev_dbg(dev,
+ "%s:Analog Device adv7180 ident %2X detected!\n", __func__,
+ adv7180_data.rev_id);
+ break;
+ case 0x40:
+ case 0x41:
+ dev_dbg(dev,
+ "%s:Analog Device adv7182 ident %2X detected!\n", __func__,
+ adv7180_data.rev_id);
+ break;
+ default:
+ dev_dbg(dev,
+ "%s:Analog Device adv7180 not detected!\n", __func__);
+ return -ENODEV;
+ }
ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
if (ret) {
diff --git a/drivers/media/platform/mxc/capture/adv7280.c b/drivers/media/platform/mxc/capture/adv7280.c
new file mode 100644
index 000000000000..b31e09ab9414
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/adv7280.c
@@ -0,0 +1,1080 @@
+/*
+ * Copyright 2016 Toradex AG.
+ *
+ * Based on adv7180/max9526 driver for iMX6 and adv7280 driver for Tegra
+ * by Antmicro
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#define ADV7280_VOLTAGE_ANALOG 1800000
+#define ADV7280_VOLTAGE_DIGITAL_CORE 1800000
+#define ADV7280_VOLTAGE_DIGITAL_IO 3300000
+#define ADV7280_VOLTAGE_PLL 1800000
+
+static struct regulator *dvddio_regulator;
+static struct regulator *dvdd_regulator;
+static struct regulator *avdd_regulator;
+static struct regulator *pvdd_regulator;
+static int pwn_gpio;
+
+struct sensor {
+ struct sensor_data sen;
+ v4l2_std_id std_id;
+ int rev_id;
+} adv7280_data;
+
+typedef enum {
+ ADV7280_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
+ ADV7280_PAL, /*!< (B, G, H, I, N)PAL video signal. */
+ ADV7280_NOT_LOCKED, /*!< Not locked on a signal. */
+} video_fmt_idx;
+
+struct video_fmt_t {
+ int v4l2_id;
+ char name[16];
+ u16 raw_width;
+ u16 raw_height;
+ u16 active_width;
+ u16 active_height;
+ int frame_rate;
+};
+
+static const struct video_fmt_t video_fmts[] = {
+ {
+ .v4l2_id = V4L2_STD_NTSC,
+ .name = "NTSC",
+ .raw_width = 720,
+ .raw_height = 525,
+ .active_width = 720,
+ .active_height = 480,
+ .frame_rate = 30,
+ },
+ {
+ .v4l2_id = V4L2_STD_PAL,
+ .name = "PAL",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .frame_rate = 25,
+ },
+ {
+ .v4l2_id = V4L2_STD_ALL,
+ .name = "Autodetect",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ .frame_rate = 0,
+ },
+};
+
+static video_fmt_idx video_idx = ADV7280_PAL;
+
+static DEFINE_MUTEX(mutex);
+
+#define IF_NAME "adv7280"
+
+#define ADV7280_INPUT_CONTROL 0x00
+#define ADV7280_VIDEO_SELECTION_1 0x01
+#define ADV7280_VIDEO_SELECTION_2 0x02
+#define ADV7280_OUTPUT_CONTROL 0x03
+#define ADV7280_EXTENDED_OUTPUT_CONTROL 0x04
+#define ADV7280_AUTODETECT_ENABLE 0x07
+#define ADV7280_BRIGHTNESS 0x0A
+#define ADV7280_ADI_CONTROL_1 0x0E
+#define ADV7280_POWER_MANAGEMENT 0x0F
+#define ADV7280_STATUS_1 0x10
+#define ADV7280_IDENT 0x11
+#define ADV7280_STATUS_3 0x13
+#define ADV7280_SHAPING_FILTER_CONTROL_1 0x17
+#define ADV7280_ADI_CONTROL_2 0x1D
+#define ADV7280_PIXEL_DELAY_CONTROL 0x27
+#define ADV7280_VPP_SLAVE_ADDRESS 0xFD
+#define ADV7280_OUTPUT_SYNC_SELECT_2 0x6B
+#define ADV7280_SD_SATURATION_CB 0xe3
+#define ADV7280_SD_SATURATION_CR 0xe4
+
+#define HW_DEINT /* Enable hardware deinterlacer */
+#define VPP_SLAVE_ADDRESS 0x42
+
+#define VPP_DEINT_RESET 0x41
+#define VPP_I2C_DEINT_ENABLE 0x55
+#define VPP_ADV_TIMING_MODE_EN 0x5B
+
+#define ADV7280_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
+#define ADV7280_AUTODETECT_DEFAULT 0x7f
+
+#define ADV7280_INPUT_CONTROL_COMPOSITE_IN1 0x00
+#define ADV7280_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
+
+#define ADV7280_INPUT_CONTROL_NTSC_M 0x50
+#define ADV7280_INPUT_CONTROL_PAL60 0x60
+#define ADV7280_INPUT_CONTROL_NTSC_443 0x70
+#define ADV7280_INPUT_CONTROL_PAL_BG 0x80
+#define ADV7280_INPUT_CONTROL_PAL_N 0x90
+#define ADV7280_INPUT_CONTROL_PAL_M 0xa0
+#define ADV7280_INPUT_CONTROL_PAL_M_PED 0xb0
+#define ADV7280_INPUT_CONTROL_PAL_COMB_N 0xc0
+#define ADV7280_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
+#define ADV7280_INPUT_CONTROL_PAL_SECAM 0xe0
+
+#define ADV7280_STATUS1_IN_LOCK 0x01
+/* Autodetection results */
+#define ADV7280_STATUS1_AUTOD_MASK 0x70
+#define ADV7280_STATUS1_AUTOD_NTSM_M_J 0x00
+#define ADV7280_STATUS1_AUTOD_NTSC_4_43 0x10
+#define ADV7280_STATUS1_AUTOD_PAL_M 0x20
+#define ADV7280_STATUS1_AUTOD_PAL_60 0x30
+#define ADV7280_STATUS1_AUTOD_PAL_B_G 0x40
+#define ADV7280_STATUS1_AUTOD_SECAM 0x50
+#define ADV7280_STATUS1_AUTOD_PAL_COMB 0x60
+#define ADV7280_STATUS1_AUTOD_SECAM_525 0x70
+
+static const struct v4l2_queryctrl adv7280_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = 127,
+ .flags = 0,
+ }
+};
+
+static inline void adv7280_power_down(int enable)
+{
+ if (gpio_is_valid(pwn_gpio)) {
+ gpio_set_value_cansleep(pwn_gpio, !enable);
+ msleep(2);
+ }
+}
+
+static int adv7280_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ dvddio_regulator = devm_regulator_get(dev, "DOVDD");
+
+ if (!IS_ERR(dvddio_regulator)) {
+ regulator_set_voltage(dvddio_regulator,
+ ADV7280_VOLTAGE_DIGITAL_IO,
+ ADV7280_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(dvddio_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get io voltage\n");
+ dvddio_regulator = NULL;
+ }
+
+ dvdd_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(dvdd_regulator)) {
+ regulator_set_voltage(dvdd_regulator,
+ ADV7280_VOLTAGE_DIGITAL_CORE,
+ ADV7280_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(dvdd_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get core voltage\n");
+ dvdd_regulator = NULL;
+ }
+
+ avdd_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(avdd_regulator)) {
+ regulator_set_voltage(avdd_regulator,
+ ADV7280_VOLTAGE_ANALOG,
+ ADV7280_VOLTAGE_ANALOG);
+ ret = regulator_enable(avdd_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get analog voltage\n");
+ avdd_regulator = NULL;
+ }
+
+ pvdd_regulator = devm_regulator_get(dev, "PVDD");
+ if (!IS_ERR(pvdd_regulator)) {
+ regulator_set_voltage(pvdd_regulator,
+ ADV7280_VOLTAGE_PLL,
+ ADV7280_VOLTAGE_PLL);
+ ret = regulator_enable(pvdd_regulator);
+ if (ret) {
+ dev_err(dev, "set pll voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set pll voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get pll voltage\n");
+ pvdd_regulator = NULL;
+ }
+
+ return ret;
+}
+
+static inline int adv7280_read(u8 reg)
+{
+ int val;
+
+ val = i2c_smbus_read_byte_data(adv7280_data.sen.i2c_client, reg);
+ if (val < 0) {
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "%s:read reg error: reg=%2x\n", __func__, reg);
+ return val;
+ }
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "%s:read reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
+ return val;
+}
+
+static int adv7280_write_reg(u8 reg, u8 val)
+{
+ s32 ret;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "%s:write reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
+ ret = i2c_smbus_write_byte_data(adv7280_data.sen.i2c_client, reg, val);
+ if (ret < 0) {
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "%s:write reg error:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int adv7280_write_reg_with_client(struct i2c_client *client,
+ u8 reg, u8 val)
+{
+ s32 ret;
+
+ dev_dbg(&client->dev,
+ "%s:write reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret < 0) {
+ dev_dbg(&client->dev,
+ "%s:write reg error:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void adv7280_get_std(v4l2_std_id *std)
+{
+ int status_1, standard, idx;
+ bool locked = 0;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "In %s\n", __func__);
+
+ status_1 = adv7280_read(ADV7280_STATUS_1);
+ locked = status_1 & ADV7280_STATUS1_IN_LOCK;
+ standard = status_1 & ADV7280_STATUS1_AUTOD_MASK;
+
+ mutex_lock(&mutex);
+ *std = V4L2_STD_ALL;
+ idx = ADV7280_NOT_LOCKED;
+ if (locked) {
+ if (standard == ADV7280_STATUS1_AUTOD_PAL_B_G) {
+ *std = V4L2_STD_PAL;
+ idx = ADV7280_PAL;
+ } else if (standard == ADV7280_STATUS1_AUTOD_NTSM_M_J) {
+ *std = V4L2_STD_NTSC;
+ idx = ADV7280_NTSC;
+ }
+ }
+ mutex_unlock(&mutex);
+
+ /* This assumes autodetect which this device uses. */
+ if (*std != adv7280_data.std_id) {
+ video_idx = idx;
+ adv7280_data.std_id = *std;
+ adv7280_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ adv7280_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ }
+}
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ struct device *dev = &adv7280_data.sen.i2c_client->dev;
+
+ dev_dbg(dev, "adv7280: %s\n", __func__);
+
+ if (s == NULL) {
+ dev_err(dev, " ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
+#if 0
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 1;
+ p->u.bt656.bt_sync_correct = 1;
+#else
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 0;
+ p->u.bt656.bt_sync_correct = 0;
+#ifdef HW_DEINT
+ p->u.bt656.clock_curr = 1; /* BT656 de-interlace clock mode */
+#endif
+#endif
+ /* ADV7280 has a dedicated clock so no clock settings needed. */
+
+ return 0;
+}
+
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor *sensor = s->priv;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ if (on && !sensor->sen.on) {
+ if (adv7280_write_reg(ADV7280_POWER_MANAGEMENT, 0x04) != 0)
+ return -EIO;
+
+ msleep(400);
+
+ } else if (!on && sensor->sen.on) {
+ if (adv7280_write_reg(ADV7280_POWER_MANAGEMENT, 0x24) != 0)
+ return -EIO;
+ }
+
+ sensor->sen.on = on;
+
+ return 0;
+}
+
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ struct device *dev = &adv7280_data.sen.i2c_client->dev;
+
+ dev_dbg(dev, "adv7280: %s\n", __func__);
+
+ switch (a->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ dev_dbg(dev, " type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->sen.streamcap.capability;
+ cparm->timeperframe = sensor->sen.streamcap.timeperframe;
+ cparm->capturemode = sensor->sen.streamcap.capturemode;
+ break;
+
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ dev_dbg(dev, "ioctl_g_parm:type is unknown %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct device *dev = &adv7280_data.sen.i2c_client->dev;
+
+ dev_dbg(dev, "adv7280: %s\n", __func__);
+
+ switch (a->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ dev_dbg(dev, " type is unknown - %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct device *dev = &adv7280_data.sen.i2c_client->dev;
+ struct sensor *sensor = s->priv;
+ v4l2_std_id std;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ dev_dbg(dev, " Returning size of %dx%d\n",
+ sensor->sen.pix.width, sensor->sen.pix.height);
+ f->fmt.pix = sensor->sen.pix;
+ break;
+
+ case V4L2_BUF_TYPE_PRIVATE:
+ adv7280_get_std(&std);
+ f->fmt.pix.pixelformat = (u32)std;
+ break;
+
+ default:
+ f->fmt.pix = sensor->sen.pix;
+ break;
+ }
+
+ return 0;
+}
+
+static int ioctl_queryctrl(struct v4l2_int_device *s,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(adv7280_qctrl); i++)
+ if (qc->id && qc->id == adv7280_qctrl[i].id) {
+ *qc = adv7280_qctrl[i];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+ int sat = 0;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ adv7280_data.sen.brightness = adv7280_read(ADV7280_BRIGHTNESS);
+ vc->value = adv7280_data.sen.brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ vc->value = adv7280_data.sen.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ sat = adv7280_read(ADV7280_SD_SATURATION_CB);
+ adv7280_data.sen.saturation = sat;
+ vc->value = adv7280_data.sen.saturation;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ vc->value = adv7280_data.sen.hue;
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ vc->value = adv7280_data.sen.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ vc->value = adv7280_data.sen.blue;
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ vc->value = adv7280_data.sen.ae_mode;
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " Default case\n");
+ vc->value = 0;
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+ u8 tmp;
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ tmp = vc->value;
+ adv7280_write_reg(ADV7280_BRIGHTNESS, tmp);
+ adv7280_data.sen.brightness = vc->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ tmp = vc->value;
+ adv7280_write_reg(ADV7280_SD_SATURATION_CB, tmp);
+ adv7280_write_reg(ADV7280_SD_SATURATION_CR, tmp);
+ adv7280_data.sen.saturation = vc->value;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ " Default case\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ return retval;
+}
+
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index >= 1)
+ return -EINVAL;
+
+ fsize->discrete.width = video_fmts[video_idx].active_width;
+ fsize->discrete.height = video_fmts[video_idx].active_height;
+
+ return 0;
+}
+
+static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
+ struct v4l2_frmivalenum *fival)
+{
+ struct video_fmt_t fmt;
+ int i;
+
+ if (fival->index != 0)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(video_fmts) - 1; i++) {
+ fmt = video_fmts[i];
+ if (fival->width == fmt.active_width &&
+ fival->height == fmt.active_height) {
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = fmt.frame_rate;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
+ "adv7280_decoder");
+ ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7280;
+
+ return 0;
+}
+
+static int ioctl_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ return 0;
+}
+
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&adv7280_data.sen.i2c_client->dev, "adv7280: %s\n", __func__);
+
+ return 0;
+}
+
+static struct v4l2_int_ioctl_desc adv7280_ioctl_desc[] = {
+
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
+
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
+ {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
+
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
+
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
+ {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_framesizes},
+ {vidioc_int_enum_frameintervals_num,
+ (v4l2_int_ioctl_func *)
+ ioctl_enum_frameintervals},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave adv7280_slave = {
+ .ioctls = adv7280_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(adv7280_ioctl_desc),
+};
+
+static struct v4l2_int_device adv7280_int_device = {
+ .module = THIS_MODULE,
+ .name = "adv7280",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &adv7280_slave,
+ },
+};
+
+static int adv7280_hard_reset(void)
+{
+ int ret;
+
+ struct i2c_client vpp_client = {
+ .flags = adv7280_data.sen.i2c_client->flags,
+ .addr = VPP_SLAVE_ADDRESS,
+ .name = "ADV7280_VPP",
+ .adapter = adv7280_data.sen.i2c_client->adapter,
+ .dev = adv7280_data.sen.i2c_client->dev,
+ };
+
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "In %s\n", __func__);
+
+ /* Reset */
+ ret = adv7280_write_reg(ADV7280_POWER_MANAGEMENT, 0xA0);
+ if (ret < 0)
+ goto error;
+ msleep(10);
+
+ /* Initialize adv7280 */
+ /* Exit Power Down Mode */
+ ret = adv7280_write_reg(ADV7280_POWER_MANAGEMENT, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(ADV7280_ADI_CONTROL_1, 0x80);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x9C, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x9C, 0xFF);
+ if (ret < 0)
+ goto error;
+
+ /* Enter User Sub Map */
+ ret = adv7280_write_reg(ADV7280_ADI_CONTROL_1, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* Enable Pixel & Sync output drivers */
+ ret = adv7280_write_reg(ADV7280_OUTPUT_CONTROL, 0x0C);
+ if (ret < 0)
+ goto error;
+
+ /* Power-up INTRQ, HS & VS pads */
+ ret = adv7280_write_reg(ADV7280_EXTENDED_OUTPUT_CONTROL, 0x07);
+ if (ret < 0)
+ goto error;
+
+ /* Enable SH1 */
+ /*
+ ret = adv7280_write_reg(ADV7280_SHAPING_FILTER_CONTROL_1, 0x41);
+ if (ret < 0)
+ goto error;
+ */
+
+ /* Disable comb filtering */
+ /*
+ ret = adv7280_write_reg(0x39, 0x24);
+ if (ret < 0)
+ goto error;
+ */
+
+ /* Enable LLC output driver */
+ ret = adv7280_write_reg(ADV7280_ADI_CONTROL_2, 0x40);
+ if (ret < 0)
+ goto error;
+
+ /* VSYNC on VS/FIELD/SFL pin */
+ ret = adv7280_write_reg(ADV7280_OUTPUT_SYNC_SELECT_2, 0x01);
+ if (ret < 0)
+ goto error;
+
+ /* Enable autodetection */
+ ret = adv7280_write_reg(ADV7280_INPUT_CONTROL,
+ ADV7280_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM |
+ (ADV7280_INPUT_CONTROL_COMPOSITE_IN1 +
+ 0));
+ if (ret < 0)
+ goto error;
+
+ ret = adv7280_write_reg(ADV7280_AUTODETECT_ENABLE,
+ ADV7280_AUTODETECT_DEFAULT);
+ if (ret < 0)
+ goto error;
+
+ /* ITU-R BT.656-4 compatible */
+ /*ret = adv7280_write_reg(ADV7280_EXTENDED_OUTPUT_CONTROL,
+ ADV7280_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
+ if (ret < 0)
+ goto error;
+ */
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x52, 0xCD);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x80, 0x51);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x81, 0x51);
+ if (ret < 0)
+ goto error;
+
+ /* analog devices recommends */
+ ret = adv7280_write_reg(0x82, 0x68);
+ if (ret < 0)
+ goto error;
+
+#ifdef HW_DEINT
+ /* Set VPP Map */
+ ret = adv7280_write_reg(ADV7280_VPP_SLAVE_ADDRESS, (VPP_SLAVE_ADDRESS << 1));
+ if (ret < 0)
+ goto error;
+
+ /* VPP - not documented */
+ ret = adv7280_write_reg_with_client(&vpp_client,
+ 0xA3, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* VPP - Enbable Advanced Timing Mode */
+ ret = adv7280_write_reg_with_client(&vpp_client,
+ VPP_ADV_TIMING_MODE_EN, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* VPP - Enable Deinterlacer */
+ ret = adv7280_write_reg_with_client(&vpp_client,
+ VPP_I2C_DEINT_ENABLE, 0x80);
+ if (ret < 0)
+ goto error;
+#endif
+
+ return 0;
+
+error:
+ return ret;
+}
+
+static int adv7280_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(dev, "Required functionality not supported by I2C adapter\n");
+ return -EIO;
+ }
+
+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio))
+ dev_warn(dev, "no sensor pwdn pin available\n");
+ else {
+ ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "adv7280_pwdn");
+ if (ret < 0)
+ dev_err(dev, "no power pin available!\n");
+ }
+
+ adv7280_regulator_enable(dev);
+
+ adv7280_power_down(0);
+
+ msleep(1);
+
+ memset(&adv7280_data, 0, sizeof(adv7280_data));
+ adv7280_data.sen.i2c_client = client;
+ adv7280_data.sen.streamcap.timeperframe.denominator = 30;
+ adv7280_data.sen.streamcap.timeperframe.numerator = 1;
+ adv7280_data.std_id = V4L2_STD_ALL;
+ video_idx = ADV7280_NOT_LOCKED;
+ adv7280_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ adv7280_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ adv7280_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
+ adv7280_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
+ adv7280_data.sen.on = true;
+
+ adv7280_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(adv7280_data.sen.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ return PTR_ERR(adv7280_data.sen.sensor_clk);
+ }
+
+ ret = of_property_read_u32(dev->of_node, "mclk",
+ &adv7280_data.sen.mclk);
+ if (ret) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(
+ dev->of_node, "mclk_source",
+ (u32 *) &(adv7280_data.sen.mclk_source));
+ if (ret) {
+ dev_err(dev, "mclk_source invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "csi_id",
+ &(adv7280_data.sen.csi));
+ if (ret) {
+ dev_err(dev, "csi_id invalid\n");
+ return ret;
+ }
+
+ /* ADV7280 is always parallel IF */
+ adv7280_data.sen.mipi_camera = 0;
+
+ clk_prepare_enable(adv7280_data.sen.sensor_clk);
+
+ adv7280_data.rev_id = adv7280_read(ADV7280_IDENT);
+ switch (adv7280_data.rev_id) {
+ case 0x42:
+ dev_dbg(dev,
+ "%s:Analog Device adv7280 ident %2X detected!\n",
+ __func__, adv7280_data.rev_id);
+ break;
+ default:
+ dev_err(dev,
+ "%s:Analog Device adv7280 not detected %d!\n", __func__,
+ adv7280_data.rev_id);
+ return -ENODEV;
+
+ }
+
+ dev_dbg(dev, " type is %d (expect %d)\n",
+ adv7280_int_device.type, v4l2_int_type_slave);
+ dev_dbg(dev, " num ioctls is %d\n",
+ adv7280_int_device.u.slave->num_ioctls);
+
+ ret = adv7280_hard_reset();
+ if (ret) {
+ dev_err(dev, "error resetting adv7280\n");
+ return ret;
+ }
+
+ /* This function attaches this structure to the /dev/video0 device.
+ * The pointer in priv points to the adv7280_data structure here.*/
+ adv7280_int_device.priv = &adv7280_data;
+ ret = v4l2_int_device_register(&adv7280_int_device);
+
+ clk_disable_unprepare(adv7280_data.sen.sensor_clk);
+
+ return 0;
+}
+
+static int adv7280_detach(struct i2c_client *client)
+{
+ dev_dbg(&adv7280_data.sen.i2c_client->dev,
+ "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
+ __func__, IF_NAME, client->addr << 1, client->adapter->name);
+
+ adv7280_write_reg(ADV7280_POWER_MANAGEMENT, 0x24);
+
+ if (dvddio_regulator)
+ regulator_disable(dvddio_regulator);
+
+ if (dvdd_regulator)
+ regulator_disable(dvdd_regulator);
+
+ if (avdd_regulator)
+ regulator_disable(avdd_regulator);
+
+ if (pvdd_regulator)
+ regulator_disable(pvdd_regulator);
+
+ v4l2_int_device_unregister(&adv7280_int_device);
+
+ return 0;
+}
+
+static const struct i2c_device_id adv7280_id[] = {
+ {"adv7280", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, adv7280_id);
+
+static struct i2c_driver adv7280_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "adv7280",
+ },
+ .probe = adv7280_probe,
+ .remove = adv7280_detach,
+ .id_table = adv7280_id,
+};
+module_i2c_driver(adv7280_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("Analog Device ADV7280 video decoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/ipu_csi_enc.c b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
index 241c744bfcb0..0b722ed4c3e3 100644
--- a/drivers/media/platform/mxc/capture/ipu_csi_enc.c
+++ b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
@@ -255,7 +255,7 @@ static int csi_enc_enabling_tasks(void *private)
err = ipu_request_irq(
cam->ipu, irq, csi_enc_callback, 0, "Mxc Camera", cam);
if (err != 0) {
- printk(KERN_ERR "Error registering rot irq\n");
+ pr_err("%s: Error requesting IPU_IRQ_CSI0_OUT_EOF\n", __func__);
return err;
}
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_enc.c b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
index d1e1def371e5..8e361dcded08 100644
--- a/drivers/media/platform/mxc/capture/ipu_prp_enc.c
+++ b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
@@ -377,6 +377,7 @@ static int prp_enc_enabling_tasks(void *private)
{
cam_data *cam = (cam_data *) private;
int err = 0;
+ int irq;
CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n");
cam->dummy_frame.vaddress = dma_alloc_coherent(cam->dev,
@@ -393,15 +394,12 @@ static int prp_enc_enabling_tasks(void *private)
PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
- if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
- err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF,
- prp_enc_callback, 0, "Mxc Camera", cam);
- } else {
- err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF,
- prp_enc_callback, 0, "Mxc Camera", cam);
- }
- if (err != 0) {
- printk(KERN_ERR "Error registering rot irq\n");
+ irq = (cam->rotation >= IPU_ROTATE_90_RIGHT) ?
+ IPU_IRQ_PRP_ENC_ROT_OUT_EOF : IPU_IRQ_PRP_ENC_OUT_EOF;
+ err = ipu_request_irq(cam->ipu, irq,
+ prp_enc_callback, 0, "Mxc Camera", cam);
+ if (err) {
+ pr_err("%s: Error requesting irq=%d\n", __func__, irq);
return err;
}
diff --git a/drivers/media/platform/mxc/capture/max9526.c b/drivers/media/platform/mxc/capture/max9526.c
new file mode 100644
index 000000000000..06242b727ca2
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/max9526.c
@@ -0,0 +1,1153 @@
+/*
+ * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2015 Toradex AG All Rights Reserved.
+ * copied and adapted from adv7180.c
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file max9526.c
+ *
+ * @brief Maxim Integrated MAX9526 video decoder functions
+ *
+ * @ingroup Camera
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-chip-ident.h>
+#include "v4l2-int-device.h"
+#include "mxc_v4l2_capture.h"
+
+#if 0
+#undef dev_dbg
+#define dev_dbg(dev, format, arg...) {dev_printk(KERN_ERR, dev, format, ##arg);}
+#undef pr_debug
+#define pr_debug(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#endif
+
+#define MAX9526_VOLTAGE_ANALOG 1800000
+#define MAX9526_VOLTAGE_DIGITAL_CORE 1800000
+#define MAX9526_VOLTAGE_DIGITAL_IO 3300000
+#define MAX9526_VOLTAGE_PLL 1800000
+
+static struct regulator *dvddio_regulator;
+static struct regulator *dvdd_regulator;
+static struct regulator *avdd_regulator;
+
+static int max9526_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *id);
+static int max9526_detach(struct i2c_client *client);
+
+static const struct i2c_device_id max9526_id[] = {
+ {"max9526", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, max9526_id);
+
+static struct i2c_driver max9526_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "max9526",
+ },
+ .probe = max9526_probe,
+ .remove = max9526_detach,
+ .id_table = max9526_id,
+};
+
+/*!
+ * Maintains the information on the current state of the sensor.
+ */
+struct sensor {
+ struct sensor_data sen;
+ v4l2_std_id std_id;
+} max9526_data;
+
+
+/*! List of input video formats supported. The video formats is corresponding
+ * with v4l2 id in video_fmt_t
+ */
+typedef enum {
+ MAX9526_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
+ MAX9526_PAL, /*!< (B, G, H, I, N)PAL video signal. */
+ MAX9526_NOT_LOCKED, /*!< Not locked on a signal. */
+} video_fmt_idx;
+
+/*! Number of video standards supported (including 'not locked' signal). */
+#define MAX9526_STD_MAX (MAX9526_PAL + 1)
+
+/*! Video format structure. */
+typedef struct {
+ int v4l2_id; /*!< Video for linux ID. */
+ char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
+ u16 raw_width; /*!< Raw width. */
+ u16 raw_height; /*!< Raw height. */
+ u16 active_width; /*!< Active width. */
+ u16 active_height; /*!< Active height. */
+} video_fmt_t;
+
+/*! Description of video formats supported.
+ *
+ * PAL: raw=720x625, active=720x576.
+ * NTSC: raw=720x525, active=720x480.
+ */
+static video_fmt_t video_fmts[] = {
+ { /*! NTSC */
+ .v4l2_id = V4L2_STD_NTSC,
+ .name = "NTSC",
+ .raw_width = 720, /* SENS_FRM_WIDTH */
+ .raw_height = 525, /* SENS_FRM_HEIGHT */
+ .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
+ .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
+ },
+ { /*! (B, G, H, I, N) PAL */
+ .v4l2_id = V4L2_STD_PAL,
+ .name = "PAL",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ },
+ { /*! Unlocked standard */
+ .v4l2_id = V4L2_STD_ALL,
+ .name = "Autodetect",
+ .raw_width = 720,
+ .raw_height = 625,
+ .active_width = 720,
+ .active_height = 576,
+ },
+};
+
+/*!* Standard index of MAX9526. */
+static video_fmt_idx video_idx = MAX9526_PAL;
+
+/*! @brief This mutex is used to provide mutual exclusion.
+ *
+ * Create a mutex that can be used to provide mutually exclusive
+ * read/write access to the globally accessible data structures
+ * and variables that were defined above.
+ */
+static DEFINE_MUTEX(mutex);
+
+#define IF_NAME "max9526"
+/* registers */
+#define REG_STATUS_0 0x00
+#define REG_STATUS_1 0x01
+#define REG_IRQMASK_0 0x02
+#define REG_IRQMASK_1 0x03
+#define REG_STANDARD_SELECT_SHUTDOWN_CONTROL 0x04
+#define REG_CONTRAST 0x05
+#define REG_BRIGHTNESS 0x06
+#define REG_HUE 0x07
+#define REG_SATURATION 0x08
+#define REG_VIDEO_INPUT_SELECT_AND_CLAMP 0x09
+#define REG_GAIN_CONTROL 0x0A
+#define REG_COLOR_KILL 0x0B
+#define REG_OUTPUT_TEST_SIGNAL 0x0C
+#define REG_CLOCK_AND_OUTPUT 0x0D
+#define REG_PLL_CONTROL 0x0E
+#define REG_MISCELLANEOUS 0x0F
+
+#define I2C_RETRY_COUNT 5
+
+/* supported controls */
+/* This hasn't been fully implemented yet.
+ * This is how it should work, though. */
+static struct v4l2_queryctrl max9526_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0, /* check this value */
+ .maximum = 255, /* check this value */
+ .step = 1, /* check this value */
+ .default_value = 127, /* check this value */
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0, /* check this value */
+ .maximum = 255, /* check this value */
+ .step = 0x1, /* check this value */
+ .default_value = 127, /* check this value */
+ .flags = 0,
+ }
+};
+
+static inline void max9526_power_down(int enable)
+{
+}
+
+static int max9526_regulator_enable(struct device *dev)
+{
+ int ret = 0;
+
+ dvddio_regulator = devm_regulator_get(dev, "DVDDIO");
+
+ if (!IS_ERR(dvddio_regulator)) {
+ regulator_set_voltage(dvddio_regulator,
+ MAX9526_VOLTAGE_DIGITAL_IO,
+ MAX9526_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(dvddio_regulator);
+ if (ret) {
+ dev_err(dev, "set io voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set io voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get io voltage\n");
+ }
+
+ dvdd_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(dvdd_regulator)) {
+ regulator_set_voltage(dvdd_regulator,
+ MAX9526_VOLTAGE_DIGITAL_CORE,
+ MAX9526_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(dvdd_regulator);
+ if (ret) {
+ dev_err(dev, "set core voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set core voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get core voltage\n");
+ }
+
+ avdd_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(avdd_regulator)) {
+ regulator_set_voltage(avdd_regulator,
+ MAX9526_VOLTAGE_ANALOG,
+ MAX9526_VOLTAGE_ANALOG);
+ ret = regulator_enable(avdd_regulator);
+ if (ret) {
+ dev_err(dev, "set analog voltage failed\n");
+ return ret;
+ } else {
+ dev_dbg(dev, "set analog voltage ok\n");
+ }
+ } else {
+ dev_warn(dev, "cannot get analog voltage\n");
+ }
+
+ return ret;
+}
+
+
+/***********************************************************************
+ * I2C transfert.
+ ***********************************************************************/
+
+/*! Read one register from a MAX9526 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static inline int __max9526_read__(u8 reg)
+{
+ int val;
+ unsigned retry = 0;
+
+ do {
+ val = i2c_smbus_read_byte_data(max9526_data.sen.i2c_client, reg);
+ if (val < 0) {
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:read reg error: reg=%2x, retry %u\n", __func__, reg, retry);
+ val = -1;
+ i2c_recover_bus(max9526_data.sen.i2c_client->adapter);
+ }
+ } while ((val < 0) && (++retry < I2C_RETRY_COUNT));
+
+ if (val < 0) {
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:read reg ERROR:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ }
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:read reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
+ return val;
+}
+static inline int max9526_read(u8 reg)
+{
+ int val, last_val;
+ unsigned retry = 0;
+
+ last_val = __max9526_read__(reg);
+
+ do {
+ val = __max9526_read__(reg);
+ if (val != last_val) {
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:read reg error: reg=%2x, retry %u\n", __func__, reg, retry);
+ last_val = val;
+ val = -1;
+ msleep(1);
+ }
+ } while ((val == -1) && (++retry < I2C_RETRY_COUNT));
+ return val;
+}
+/*! Write one register of a MAX9526 i2c slave device.
+ *
+ * @param *reg register in the device we wish to access.
+ *
+ * @return 0 if success, an error code otherwise.
+ */
+static int max9526_write_reg(u8 reg, u8 val)
+{
+ s32 ret = 0;
+ unsigned retry = 0;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:write reg 0x%2x, val: 0x%2x\n", __func__, reg, val);
+
+ do {
+ ret = i2c_smbus_write_byte_data(max9526_data.sen.i2c_client, reg, val);
+ if (ret < 0) {
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:write reg error:reg=%2x,val=%2x, retry %u\n", __func__,
+ reg, val, retry+1);
+ ret = -1;
+ i2c_recover_bus(max9526_data.sen.i2c_client->adapter);
+ }
+ } while ((ret < 0) && (++retry < I2C_RETRY_COUNT));
+
+ if (ret < 0) {
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:write reg ERROR:reg=%2x,val=%2x\n", __func__,
+ reg, val);
+ }
+
+ return ret;
+}
+
+/***********************************************************************
+ * mxc_v4l2_capture interface.
+ ***********************************************************************/
+
+/*!
+ * Return attributes of current video standard.
+ * Since this device autodetects the current standard, this function also
+ * sets the values that need to be changed if the standard changes.
+ * There is no set std equivalent function.
+ *
+ * @return None.
+ */
+static void max9526_get_std(v4l2_std_id *std)
+{
+ int tmp = 0;
+ int idx;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526_get_std\n");
+
+ /* reset the status flag to get current state */
+#if 0
+ (void) max9526_read(REG_STATUS_0);
+ msleep(1);
+ tmp = max9526_read(REG_STATUS_0) & 0x1;
+#endif
+ tmp |= max9526_read(REG_STATUS_1) & 0x40;
+
+ mutex_lock(&mutex);
+ if (tmp == 0x0) {
+ /* PAL */
+ *std = V4L2_STD_PAL;
+ idx = MAX9526_PAL;
+ } else if (tmp == 0x40) {
+ /*NTSC*/
+ *std = V4L2_STD_NTSC;
+ idx = MAX9526_NTSC;
+ } else {
+ *std = V4L2_STD_ALL;
+ idx = MAX9526_NOT_LOCKED;
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "Got invalid video standard!\n");
+ }
+ mutex_unlock(&mutex);
+
+ /* This assumes autodetect which this device uses. */
+ if (*std != max9526_data.std_id) {
+ video_idx = idx;
+ max9526_data.std_id = *std;
+ max9526_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ max9526_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ }
+}
+
+/***********************************************************************
+ * IOCTL Functions from v4l2_int_ioctl_desc.
+ ***********************************************************************/
+
+/*!
+ * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
+ * s: pointer to standard V4L2 device structure
+ * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
+ *
+ * Gets slave interface parameters.
+ * Calculates the required xclk value to support the requested
+ * clock parameters in p. This value is returned in the p
+ * parameter.
+ *
+ * vidioc_int_g_ifparm returns platform-specific information about the
+ * interface settings used by the sensor.
+ *
+ * Called on open.
+ */
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "max9526:ioctl_g_ifparm\n");
+
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ /* Initialize structure to 0s then set any non-0 values. */
+ memset(p, 0, sizeof(*p));
+ p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
+#if 0
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 1;
+ p->u.bt656.bt_sync_correct = 1;
+#elif 0
+//working for PAL
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.nobt_hs_inv = 0;
+ p->u.bt656.bt_sync_correct = 0;
+ p->u.bt656.clock_curr = 0; //BT656 interlace clock mode
+#else
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT;
+ p->u.bt656.nobt_hs_inv = 1;
+ p->u.bt656.nobt_vs_inv = 1;
+ p->u.bt656.bt_sync_correct = 0;
+ p->u.bt656.clock_curr = 0; //BT656 interlace clock mode
+#endif
+ /* MAX9526 has a dedicated clock so no clock settings needed. */
+
+ return 0;
+}
+
+/*!
+ * Sets the camera power.
+ *
+ * s pointer to the camera device
+ * on if 1, power is to be turned on. 0 means power is to be turned off
+ *
+ * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
+ * @s: pointer to standard V4L2 device structure
+ * @on: power state to which device is to be set
+ *
+ * Sets devices power state to requrested state, if possible.
+ * This is called on open, close, suspend and resume.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor *sensor = s->priv;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "max9526:ioctl_s_power\n");
+
+ if (on && !sensor->sen.on) {
+ if (max9526_write_reg(REG_STANDARD_SELECT_SHUTDOWN_CONTROL, 0x10) != 0)
+ return -EIO;
+
+ /*
+ * FIXME:Additional 400ms to wait the chip to be stable?
+ * This is a workaround for preview scrolling issue.
+ * Taken from ADV7180, really needed on MAX9526??
+ */
+ msleep(400);
+
+ } else if (!on && sensor->sen.on) {
+ if (max9526_write_reg(REG_STANDARD_SELECT_SHUTDOWN_CONTROL, 0x18) != 0)
+ return -EIO;
+ }
+
+ sensor->sen.on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526:ioctl_g_parm\n");
+
+ switch (a->type) {
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->sen.streamcap.capability;
+ cparm->timeperframe = sensor->sen.streamcap.timeperframe;
+ cparm->capturemode = sensor->sen.streamcap.capturemode;
+ break;
+
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ *
+ * This driver cannot change these settings.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526:ioctl_s_parm\n");
+
+ switch (a->type) {
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor *sensor = s->priv;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "max9526:ioctl_g_fmt_cap\n");
+ //dump_stack();
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ pr_debug(" Returning size of %dx%d\n",
+ sensor->sen.pix.width, sensor->sen.pix.height);
+ f->fmt.pix = sensor->sen.pix;
+ break;
+
+ case V4L2_BUF_TYPE_PRIVATE: {
+ v4l2_std_id std;
+ max9526_get_std(&std);
+ f->fmt.pix.pixelformat = (u32)std;
+ }
+ break;
+
+ default:
+ f->fmt.pix = sensor->sen.pix;
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control information
+ * from the video_control[] array. Otherwise, returns -EINVAL if the
+ * control is not supported.
+ */
+static int ioctl_queryctrl(struct v4l2_int_device *s,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "max9526:ioctl_queryctrl\n");
+
+ for (i = 0; i < ARRAY_SIZE(max9526_qctrl); i++)
+ if (qc->id && qc->id == max9526_qctrl[i].id) {
+ memcpy(qc, &(max9526_qctrl[i]),
+ sizeof(*qc));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+ int sat = 0;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526:ioctl_g_ctrl\n");
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ max9526_data.sen.brightness = max9526_read(REG_BRIGHTNESS);
+ vc->value = max9526_data.sen.brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ vc->value = max9526_data.sen.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ sat = max9526_read(REG_SATURATION);
+ max9526_data.sen.saturation = sat;
+ vc->value = max9526_data.sen.saturation;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ vc->value = max9526_data.sen.hue;
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ vc->value = max9526_data.sen.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ vc->value = max9526_data.sen.blue;
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ vc->value = max9526_data.sen.ae_mode;
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " Default case\n");
+ vc->value = 0;
+ ret = -EPERM;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+ u8 tmp;
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526:ioctl_s_ctrl\n");
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_BRIGHTNESS\n");
+ tmp = vc->value;
+ max9526_write_reg(REG_BRIGHTNESS, tmp);
+ max9526_data.sen.brightness = vc->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_CONTRAST\n");
+ break;
+ case V4L2_CID_SATURATION:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_SATURATION\n");
+ tmp = vc->value;
+ max9526_write_reg(REG_SATURATION, tmp);
+ max9526_data.sen.saturation = vc->value;
+ break;
+ case V4L2_CID_HUE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_HUE\n");
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_DO_WHITE_BALANCE\n");
+ break;
+ case V4L2_CID_RED_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_RED_BALANCE\n");
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_BLUE_BALANCE\n");
+ break;
+ case V4L2_CID_GAMMA:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_GAMMA\n");
+ break;
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_EXPOSURE\n");
+ break;
+ case V4L2_CID_AUTOGAIN:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_AUTOGAIN\n");
+ break;
+ case V4L2_CID_GAIN:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_GAIN\n");
+ break;
+ case V4L2_CID_HFLIP:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_HFLIP\n");
+ break;
+ case V4L2_CID_VFLIP:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " V4L2_CID_VFLIP\n");
+ break;
+ default:
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ " Default case\n");
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index >= 1)
+ return -EINVAL;
+
+ fsize->discrete.width = video_fmts[video_idx].active_width;
+ fsize->discrete.height = video_fmts[video_idx].active_height;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
+ "max9526_decoder");
+ ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_AMBIGUOUS;
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526:ioctl_init\n");
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "max9526:ioctl_dev_init\n");
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module.
+ */
+static struct v4l2_int_ioctl_desc max9526_ioctl_desc[] = {
+
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
+
+ /*!
+ * Delinitialise the dev. at slave detach.
+ * The complement of ioctl_dev_init.
+ */
+/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
+
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
+/* {vidioc_int_g_needs_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
+/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
+ {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
+
+ /*!
+ * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
+ */
+/* {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
+
+ /*!
+ * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
+ * This ioctl is used to negotiate the image capture size and
+ * pixel format without actually making it take effect.
+ */
+/* {vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
+
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
+
+ /*!
+ * If the requested format is supported, configures the HW to use that
+ * format, returns error code if format not supported or HW can't be
+ * correctly configured.
+ */
+/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
+
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
+ {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave max9526_slave = {
+ .ioctls = max9526_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(max9526_ioctl_desc),
+};
+
+static struct v4l2_int_device max9526_int_device = {
+ .module = THIS_MODULE,
+ .name = "max9526",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &max9526_slave,
+ },
+};
+
+
+/***********************************************************************
+ * I2C client and driver.
+ ***********************************************************************/
+
+/*! MAX9526 Reset function.
+ *
+ * @return None.
+ */
+static void max9526_hard_reset(void)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "In max9526:max9526_hard_reset\n");
+
+ /* System Reset */
+ max9526_write_reg(REG_STANDARD_SELECT_SHUTDOWN_CONTROL, 0x04);
+ msleep(10);
+
+ /* Delta to Datasheet poweron state */
+ max9526_write_reg(REG_STANDARD_SELECT_SHUTDOWN_CONTROL, 0x18); /* shutdown */
+ max9526_write_reg(REG_VIDEO_INPUT_SELECT_AND_CLAMP, 0x82); /* autom. input sel. */
+ max9526_write_reg(REG_OUTPUT_TEST_SIGNAL, 0x03); /* select 100% color bars */
+ max9526_write_reg(REG_CLOCK_AND_OUTPUT, 0x04); /* Output HSync/Vsync */
+ max9526_write_reg(REG_MISCELLANEOUS, 0x14); /* Output HSync/Vsync */
+}
+
+/*! MAX9526 I2C attach function.
+ *
+ * @param *adapter struct i2c_adapter *.
+ *
+ * @return Error code indicating success or failure.
+ */
+
+/*!
+ * MAX9526 I2C probe function.
+ * Function set in i2c_driver struct.
+ * Called by insmod.
+ *
+ * @param *adapter I2C adapter descriptor.
+ *
+ * @return Error code indicating success or failure.
+ */
+static int max9526_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+
+ dev_dbg(dev, "%s sensor data is at %p\n", __func__, &max9526_data);
+
+ /* Set initial values for the sensor struct. */
+ memset(&max9526_data, 0, sizeof(max9526_data));
+ max9526_data.sen.i2c_client = client;
+ max9526_data.sen.streamcap.timeperframe.denominator = 30;
+ max9526_data.sen.streamcap.timeperframe.numerator = 1;
+ max9526_data.std_id = V4L2_STD_ALL;
+ video_idx = MAX9526_NOT_LOCKED;
+ max9526_data.sen.pix.width = video_fmts[video_idx].raw_width;
+ max9526_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ max9526_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
+ max9526_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
+ max9526_data.sen.on = false;
+
+ max9526_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(max9526_data.sen.sensor_clk)) {
+ dev_err(dev, "get mclk failed\n");
+ return PTR_ERR(max9526_data.sen.sensor_clk);
+ }
+
+ ret = of_property_read_u32(dev->of_node, "mclk",
+ &max9526_data.sen.mclk);
+ if (ret) {
+ dev_err(dev, "mclk frequency is invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(
+ dev->of_node, "mclk_source",
+ (u32 *) &(max9526_data.sen.mclk_source));
+ if (ret) {
+ dev_err(dev, "mclk_source invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "csi_id",
+ &(max9526_data.sen.csi));
+ if (ret) {
+ dev_err(dev, "csi_id invalid\n");
+ return ret;
+ }
+
+ /* MAX9526 is always parallel IF */
+ max9526_data.sen.mipi_camera = 0;
+
+ clk_prepare_enable(max9526_data.sen.sensor_clk);
+
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:max9526 probe i2c address is 0x%02X\n",
+ __func__, max9526_data.sen.i2c_client->addr);
+
+ /*! Read a register to test I2C device address */
+ ret = max9526_read(REG_MISCELLANEOUS) & 0xd0;
+ if(ret != 0x10) {
+ /* if the first read fails, that might go undetected */
+ ret = max9526_read(REG_MISCELLANEOUS) & 0xd0;
+ if(ret != 0x10) {
+ dev_err(dev, "Device seems not to be a MAX9526\n");
+ return -ENODEV;
+ }
+ }
+
+ /* MAX9526 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "setup pinctrl failed\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ max9526_regulator_enable(dev);
+
+ max9526_power_down(0);
+
+ msleep(1);
+
+ /*! MAX9526 initialization. */
+ max9526_hard_reset();
+
+ pr_debug(" type is %d (expect %d)\n",
+ max9526_int_device.type, v4l2_int_type_slave);
+ pr_debug(" num ioctls is %d\n",
+ max9526_int_device.u.slave->num_ioctls);
+
+ /* This function attaches this structure to the /dev/video0 device.
+ * The pointer in priv points to the max9526_data structure here.*/
+ max9526_int_device.priv = &max9526_data;
+ ret = v4l2_int_device_register(&max9526_int_device);
+
+ clk_disable_unprepare(max9526_data.sen.sensor_clk);
+
+ return ret;
+}
+
+/*!
+ * MAX9526 I2C detach function.
+ * Called on rmmod.
+ *
+ * @param *client struct i2c_client*.
+ *
+ * @return Error code indicating success or failure.
+ */
+static int max9526_detach(struct i2c_client *client)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev,
+ "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
+ __func__, IF_NAME, client->addr << 1, client->adapter->name);
+
+ /* Power down via i2c */
+ max9526_write_reg(REG_STANDARD_SELECT_SHUTDOWN_CONTROL, 0x18);
+
+ if (dvddio_regulator)
+ regulator_disable(dvddio_regulator);
+
+ if (dvdd_regulator)
+ regulator_disable(dvdd_regulator);
+
+ if (avdd_regulator)
+ regulator_disable(avdd_regulator);
+
+ v4l2_int_device_unregister(&max9526_int_device);
+
+ return 0;
+}
+
+/*!
+ * MAX9526 init function.
+ * Called on insmod.
+ *
+ * @return Error code indicating success or failure.
+ */
+static __init int max9526_init(void)
+{
+ u8 err = 0;
+
+ pr_debug("In max9526_init\n");
+
+ /* Tells the i2c driver what functions to call for this driver. */
+ err = i2c_add_driver(&max9526_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * MAX9526 cleanup function.
+ * Called on rmmod.
+ *
+ * @return Error code indicating success or failure.
+ */
+static void __exit max9526_clean(void)
+{
+ dev_dbg(&max9526_data.sen.i2c_client->dev, "In max9526_clean\n");
+ i2c_del_driver(&max9526_i2c_driver);
+}
+
+module_init(max9526_init);
+module_exit(max9526_clean);
+
+MODULE_AUTHOR("max.krummenacher@toradex.com");
+MODULE_DESCRIPTION("Maxim Integrated MAX9526 video decoder driver for i.MX6");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mxc/capture/mxc_mipi_csi.c b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c
index 069a0b9bb961..e489c83adea3 100644
--- a/drivers/media/platform/mxc/capture/mxc_mipi_csi.c
+++ b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c
@@ -954,9 +954,13 @@ static int mipi_csis_parse_dt(struct platform_device *pdev,
&state->max_num_lanes))
return -EINVAL;
- node = of_graph_get_next_endpoint(node, NULL);
+ /*
+ * Explicitly get endpoint 1 being the sensor one as using overlays may
+ * reverse node order in the final device tree blob.
+ */
+ node = of_graph_get_endpoint_by_regs(node, 0, 1);
if (!node) {
- dev_err(&pdev->dev, "No port node at %s\n",
+ dev_err(&pdev->dev, "No port/endpoint 1 sensor node at %s\n",
pdev->dev.of_node->full_name);
return -EINVAL;
}
@@ -988,38 +992,39 @@ static const struct v4l2_async_notifier_operations mxc_mipi_csi_subdev_ops = {
static int mipi_csis_subdev_host(struct csi_state *state)
{
struct device_node *parent = state->dev->of_node;
- struct device_node *node, *port, *rem;
+ struct device_node *node, *rem;
int ret;
v4l2_async_notifier_init(&state->subdev_notifier);
- /* Attach sensors linked to csi receivers */
- for_each_available_child_of_node(parent, node) {
- if (of_node_cmp(node->name, "port"))
- continue;
-
- /* The csi node can have only port subnode. */
- port = of_get_next_child(node, NULL);
- if (!port)
- continue;
- rem = of_graph_get_remote_port_parent(port);
- of_node_put(port);
- if (rem == NULL) {
- v4l2_info(&state->v4l2_dev,
- "Remote device at %s not found\n",
- port->full_name);
- return -1;
- }
-
- INIT_LIST_HEAD(&state->asd.list);
- state->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- state->asd.match.fwnode = of_fwnode_handle(rem);
- state->async_subdevs[0] = &state->asd;
+ /*
+ * Explicitly get endpoint 1 being the sensor one as using overlays may
+ * reverse node order in the final device tree blob.
+ */
+ node = of_graph_get_endpoint_by_regs(parent, 0, 1);
+ if (node == NULL) {
+ v4l2_info(&state->v4l2_dev,
+ "Port at %s not found\n",
+ parent->full_name);
+ return -1;
+ }
- of_node_put(rem);
- break;
+ rem = of_graph_get_remote_port_parent(node);
+ of_node_put(node);
+ if (rem == NULL) {
+ v4l2_info(&state->v4l2_dev,
+ "Remote device at %s not found\n",
+ node->full_name);
+ return -1;
}
+ INIT_LIST_HEAD(&state->asd.list);
+ state->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ state->asd.match.fwnode = of_fwnode_handle(rem);
+ state->async_subdevs[0] = &state->asd;
+
+ of_node_put(rem);
+
ret = v4l2_async_notifier_add_subdev(&state->subdev_notifier,
&state->asd);
if (ret) {
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
index 936514db9944..4fdec11be414 100644
--- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
@@ -27,8 +27,12 @@
#include <linux/fb.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/mutex.h>
#include <linux/mxcfb.h>
#include <linux/of_device.h>
+#include <linux/regmap.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
@@ -37,6 +41,13 @@
#include "mxc_v4l2_capture.h"
#include "ipu_prp_sw.h"
+#if 0
+#undef dev_dbg
+#define dev_dbg(dev, format, arg...) {dev_printk(KERN_ERR, dev, format, ##arg);}
+#undef pr_debug
+#define pr_debug(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#endif
+
#define init_MUTEX(sem) sema_init(sem, 1)
static struct platform_device_id imx_v4l2_devtype[] = {
@@ -986,7 +997,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->bright = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_BRIGHTNESS\n");
status = -ENODEV;
}
break;
@@ -996,7 +1007,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->hue = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_HUE\n");
status = -ENODEV;
}
break;
@@ -1006,7 +1017,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->contrast = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_CONTRAST\n");
status = -ENODEV;
}
break;
@@ -1016,7 +1027,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->saturation = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_SATURATION\n");
status = -ENODEV;
}
break;
@@ -1026,7 +1037,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->red = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_RED_BALANCE\n");
status = -ENODEV;
}
break;
@@ -1036,7 +1047,7 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->blue = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_BLUE_BALANCE\n");
status = -ENODEV;
}
break;
@@ -1046,12 +1057,12 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
status = vidioc_int_g_ctrl(cam->sensor, c);
cam->ae_mode = c->value;
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_BLACK_LEVEL\n");
status = -ENODEV;
}
break;
default:
- pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
+ pr_debug("ERROR: v4l2 capture: unsupported ioctrl!\n");
}
return status;
@@ -1156,7 +1167,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->hue = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_HUE\n");
ret = -ENODEV;
}
break;
@@ -1165,7 +1176,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->contrast = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_CONTRAST\n");
ret = -ENODEV;
}
break;
@@ -1174,7 +1185,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->bright = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_BRIGHTNESS\n");
ret = -ENODEV;
}
break;
@@ -1183,7 +1194,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->saturation = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_SATURATION\n");
ret = -ENODEV;
}
break;
@@ -1192,7 +1203,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->red = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_RED_BALANCE\n");
ret = -ENODEV;
}
break;
@@ -1201,7 +1212,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->blue = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_BLUE_BALANCE\n");
ret = -ENODEV;
}
break;
@@ -1210,7 +1221,7 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
cam->ae_mode = c->value;
ret = vidioc_int_s_ctrl(cam->sensor, c);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_EXPOSURE\n");
ret = -ENODEV;
}
break;
@@ -1340,6 +1351,8 @@ static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
if (ifparm.u.bt656.clock_curr == 0)
csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
+ else if (ifparm.u.bt656.clock_curr == 1)
+ csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE;
else
csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
@@ -1548,6 +1561,39 @@ static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
return retval;
}
+static void power_down_callback(struct work_struct *work)
+{
+ cam_data *cam = container_of(work, struct _cam_data, power_down_work.work);
+
+ down(&cam->busy_lock);
+ if (!cam->open_count) {
+ vidioc_int_s_power(cam->sensor, 0);
+ cam->power_on = 0;
+ }
+ up(&cam->busy_lock);
+}
+
+/* cam->busy_lock is held */
+void power_up_camera(cam_data *cam)
+{
+ if (cam->power_on) {
+ cancel_delayed_work(&cam->power_down_work);
+ return;
+ }
+ vidioc_int_s_power(cam->sensor, 1);
+ vidioc_int_init(cam->sensor);
+ vidioc_int_dev_init(cam->sensor);
+ cam->power_on = 1;
+}
+
+
+void power_off_camera(cam_data *cam)
+{
+ schedule_delayed_work(&cam->power_down_work, (HZ * 2));
+}
+
+unsigned long csi_in_use;
+
/*!
* V4L interface - open function
*
@@ -1565,6 +1611,7 @@ static int mxc_v4l_open(struct file *file)
cam_data *cam = video_get_drvdata(dev);
int err = 0;
struct sensor_data *sensor;
+ int csi_bit;
pr_debug("\nIn MVC: mxc_v4l_open\n");
pr_debug(" device name is %s\n", dev->name);
@@ -1577,7 +1624,7 @@ static int mxc_v4l_open(struct file *file)
if (cam->sensor == NULL ||
cam->sensor->type != v4l2_int_type_slave) {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! V4L2_CID_HUE\n");
return -EAGAIN;
}
@@ -1589,11 +1636,45 @@ static int mxc_v4l_open(struct file *file)
}
down(&cam->busy_lock);
+
err = 0;
if (signal_pending(current))
goto oops;
if (cam->open_count++ == 0) {
+ struct regmap *gpr;
+
+ csi_bit = (cam->ipu_id << 1) | cam->csi;
+ if (test_and_set_bit(csi_bit, &csi_in_use)) {
+ pr_err("%s: %s CSI already in use\n", __func__, dev->name);
+ err = -EBUSY;
+ cam->open_count = 0;
+ goto oops;
+ }
+ cam->csi_in_use = 1;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ if (of_machine_is_compatible("fsl,imx6q")) {
+ if (cam->ipu_id == cam->csi) {
+ unsigned shift = 19 + cam->csi;
+ unsigned mask = 1 << shift;
+ unsigned val = (cam->mipi_camera ? 0 : 1) << shift;
+
+ regmap_update_bits(gpr, IOMUXC_GPR1, mask, val);
+ }
+ } else if (of_machine_is_compatible("fsl,imx6dl")) {
+ unsigned shift = cam->csi * 3;
+ unsigned mask = 7 << shift;
+ unsigned val = (cam->mipi_camera ? csi_bit : 4) << shift;
+
+ regmap_update_bits(gpr, IOMUXC_GPR13, mask, val);
+ }
+ } else {
+ pr_err("%s: failed to find fsl,imx6q-iomux-gpr regmap\n",
+ __func__);
+ }
+
wait_event_interruptible(cam->power_queue,
cam->low_power == false);
@@ -1691,9 +1772,7 @@ static int mxc_v4l_open(struct file *file)
cam_fmt.fmt.pix.pixelformat,
csi_param);
clk_prepare_enable(sensor->sensor_clk);
- vidioc_int_s_power(cam->sensor, 1);
- vidioc_int_init(cam->sensor);
- vidioc_int_dev_init(cam->sensor);
+ power_up_camera(cam);
}
file->private_data = dev;
@@ -1750,7 +1829,6 @@ static int mxc_v4l_close(struct file *file)
}
if (--cam->open_count == 0) {
- vidioc_int_s_power(cam->sensor, 0);
clk_disable_unprepare(sensor->sensor_clk);
wait_event_interruptible(cam->power_queue,
cam->low_power == false);
@@ -1775,6 +1853,14 @@ static int mxc_v4l_close(struct file *file)
wake_up_interruptible(&cam->enc_queue);
mxc_free_frames(cam);
cam->enc_counter++;
+ power_off_camera(cam);
+
+ if (cam->csi_in_use) {
+ int csi_bit = (cam->ipu_id << 1) | cam->csi;
+
+ clear_bit(csi_bit, &csi_in_use);
+ cam->csi_in_use = 0;
+ }
}
up(&cam->busy_lock);
@@ -2219,7 +2305,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = vidioc_int_g_parm(cam->sensor, parm);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_G_PARM\n");
retval = -ENODEV;
}
break;
@@ -2231,7 +2317,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = mxc_v4l2_s_param(cam, parm);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_S_PARM\n");
retval = -ENODEV;
}
break;
@@ -2241,6 +2327,10 @@ static long mxc_v4l_do_ioctl(struct file *file,
case VIDIOC_ENUMSTD: {
struct v4l2_standard *e = arg;
pr_debug(" case VIDIOC_ENUMSTD\n");
+ if (e->index > 0) {
+ retval = -EINVAL;
+ break;
+ }
*e = cam->standard;
break;
}
@@ -2251,7 +2341,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = mxc_v4l2_g_std(cam, e);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_G_STD\n");
retval = -ENODEV;
}
break;
@@ -2356,7 +2446,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_ENUM_FMT\n");
retval = -ENODEV;
}
break;
@@ -2366,7 +2456,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_ENUM_FRAMESIZES\n");
retval = -ENODEV;
}
break;
@@ -2377,7 +2467,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
retval = vidioc_int_enum_frameintervals(cam->sensor,
fival);
} else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_ENUM_FRAMEINTERVALS\n");
retval = -ENODEV;
}
break;
@@ -2389,7 +2479,7 @@ static long mxc_v4l_do_ioctl(struct file *file,
if (cam->sensor)
retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
+ pr_err("ERROR: v4l2 capture: slave not found! VIDIOC_DBG_G_CHIP_IDENT\n");
retval = -ENODEV;
}
break;
@@ -2617,9 +2707,10 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
const struct of_device_id *of_id =
of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
struct device_node *np = pdev->dev.of_node;
- int ipu_id, csi_id, mclk_source;
+ int ipu_id, csi_id, mclk_source, mipi_camera;
int ret = 0;
struct v4l2_device *v4l2_dev;
+ static int camera_id;
pr_debug("In MVC: init_camera_struct\n");
@@ -2641,6 +2732,10 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
return ret;
}
+ ret = of_property_read_u32(np, "mipi_camera", &mipi_camera);
+ if (ret)
+ mipi_camera = 0;
+
/* Default everything to 0 */
memset(cam, 0, sizeof(cam_data));
@@ -2663,6 +2758,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
init_MUTEX(&cam->param_lock);
init_MUTEX(&cam->busy_lock);
+ INIT_DELAYED_WORK(&cam->power_down_work, power_down_callback);
cam->video_dev = video_device_alloc();
if (cam->video_dev == NULL)
@@ -2729,6 +2825,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
cam->ipu_id = ipu_id;
cam->csi = csi_id;
+ cam->mipi_camera = mipi_camera;
cam->mclk_source = mclk_source;
cam->mclk_on[cam->mclk_source] = false;
@@ -2739,7 +2836,7 @@ static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
cam->self->module = THIS_MODULE;
- sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
+ sprintf(cam->self->name, "mxc_v4l2_cap%d", camera_id++);
cam->self->type = v4l2_int_type_master;
cam->self->u.master = &mxc_v4l2_master;
@@ -2951,7 +3048,8 @@ static int mxc_v4l2_resume(struct platform_device *pdev)
wake_up_interruptible(&cam->power_queue);
if (cam->sensor && cam->open_count) {
- vidioc_int_s_power(cam->sensor, 1);
+ if ((cam->overlay_on == true) || (cam->capture_on == true))
+ vidioc_int_s_power(cam->sensor, 1);
if (!cam->mclk_on[cam->mclk_source]) {
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
@@ -3012,8 +3110,9 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
return -1;
}
- if (sdata->csi != cam->csi) {
- pr_debug("%s: csi doesn't match\n", __func__);
+ if ((sdata->ipu_id != cam->ipu_id) || (sdata->csi != cam->csi) || (sdata->mipi_camera != cam->mipi_camera)) {
+ pr_info("%s: ipu(%d:%d)/csi(%d:%d)/mipi(%d:%d) doesn't match\n", __func__,
+ sdata->ipu_id, cam->ipu_id, sdata->csi, cam->csi, sdata->mipi_camera, cam->mipi_camera);
return -1;
}
@@ -3067,6 +3166,10 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
__func__,
cam->crop_current.width, cam->crop_current.height);
+ pr_info("%s: ipu%d:/csi%d %s attached %s:%s\n", __func__,
+ cam->ipu_id, cam->csi, cam->mipi_camera ? "mipi" : "parallel",
+ slave->name, slave->u.slave->master->name);
+
return 0;
}
@@ -3100,6 +3203,20 @@ static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
vidioc_int_dev_exit(slave);
}
+DEFINE_MUTEX(camera_common_mutex);
+
+void mxc_camera_common_lock(void)
+{
+ mutex_lock(&camera_common_mutex);
+}
+EXPORT_SYMBOL(mxc_camera_common_lock);
+
+void mxc_camera_common_unlock(void)
+{
+ mutex_unlock(&camera_common_mutex);
+}
+EXPORT_SYMBOL(mxc_camera_common_unlock);
+
/*!
* Entry point for the V4L2
*
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
index 6c800cb7b8de..c0a6fef2205e 100644
--- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
@@ -108,6 +108,8 @@ typedef struct _cam_data {
struct semaphore busy_lock;
int open_count;
+ struct delayed_work power_down_work;
+ int power_on;
/* params lock for this camera */
struct semaphore param_lock;
@@ -201,6 +203,8 @@ typedef struct _cam_data {
wait_queue_head_t power_queue;
unsigned int ipu_id;
unsigned int csi;
+ unsigned mipi_camera;
+ int csi_in_use;
u8 mclk_source;
bool mclk_on[2]; /* two mclk sources at most now */
int current_input;
@@ -247,10 +251,15 @@ struct sensor_data {
u32 mclk;
u8 mclk_source;
struct clk *sensor_clk;
+ int ipu_id;
int csi;
+ int mipi_camera; /* 0: parallel camera hw if, != 0: mipi csi hw if */
void (*io_init)(void);
};
void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
+void mxc_camera_common_lock(void);
+void mxc_camera_common_unlock(void);
+
#endif /* __MXC_V4L2_CAPTURE_H__ */
diff --git a/drivers/media/platform/mxc/capture/ov5640_mipi.c b/drivers/media/platform/mxc/capture/ov5640_mipi.c
index 118174af2c65..0245808efc14 100644
--- a/drivers/media/platform/mxc/capture/ov5640_mipi.c
+++ b/drivers/media/platform/mxc/capture/ov5640_mipi.c
@@ -28,8 +28,12 @@
#include <linux/clk.h>
#include <linux/of_device.h>
#include <linux/i2c.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/fsl_devices.h>
#include <linux/mipi_csi2.h>
@@ -699,12 +703,40 @@ static void ov5640_standby(s32 enable)
gpio_set_value(pwn_gpio, 1);
else
gpio_set_value(pwn_gpio, 0);
-
+ pr_debug("ov5640_mipi_camera_powerdown: powerdown=%x, power_gp=0x%x\n", enable, pwn_gpio);
msleep(100);
}
+static s32 update_device_addr(struct sensor_data *sensor)
+{
+ int ret;
+ u8 buf[4];
+ unsigned reg = 0x3100;
+ unsigned default_addr = 0x3c;
+ struct i2c_msg msg;
+
+ if (sensor->i2c_client->addr == default_addr)
+ return 0;
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = sensor->i2c_client->addr << 1;
+ msg.addr = default_addr;
+ msg.flags = 0;
+ msg.len = 3;
+ msg.buf = buf;
+
+
+ ret = i2c_transfer(sensor->i2c_client->adapter, &msg, 1);
+ if (ret < 0)
+ pr_err("%s: ov5642 ret=%d\n", __func__, ret);
+ return ret;
+}
+
static void ov5640_reset(void)
{
+ mxc_camera_common_lock();
+
/* camera reset */
gpio_set_value(rst_gpio, 1);
@@ -719,7 +751,9 @@ static void ov5640_reset(void)
msleep(1);
gpio_set_value(rst_gpio, 1);
- msleep(5);
+ msleep(20);
+ update_device_addr(&ov5640_data);
+ mxc_camera_common_unlock();
gpio_set_value(pwn_gpio, 1);
}
@@ -803,18 +837,33 @@ static void ov5640_power_off(void)
static s32 ov5640_write_reg(u16 reg, u8 val)
{
+ int ret;
u8 au8Buf[3] = {0};
au8Buf[0] = reg >> 8;
au8Buf[1] = reg & 0xff;
au8Buf[2] = val;
- if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
- pr_err("%s:write reg error:reg=%x,val=%x\n",
- __func__, reg, val);
- return -1;
+#if 0 /* Software reset does not affect the i2c address register like it does on ov5642 */
+ if ((reg == 0x3008) && (val & 0x80)) {
+ mxc_camera_common_lock();
+
+ ret = i2c_master_send(ov5640_data.i2c_client, au8Buf, 3);
+ update_device_addr(&ov5640_data);
+
+ mxc_camera_common_unlock();
+ } else
+#endif
+ {
+ ret = i2c_master_send(ov5640_data.i2c_client, au8Buf, 3);
}
+ if (ret < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x ret=%d\n",
+ __func__, reg, val, ret);
+ return ret;
+ }
+ pr_debug("reg=%x,val=%x\n", reg, val);
return 0;
}
@@ -856,43 +905,64 @@ static void OV5640_stream_off(void)
ov5640_write_reg(0x4202, 0x0f);
}
-
+static const int sclk_rdiv_map[] = {1, 2, 4, 8};
+
static int OV5640_get_sysclk(void)
{
/* calculate sysclk */
- int xvclk = ov5640_data.mclk / 10000;
- int temp1, temp2;
- int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
- int Bit_div2x = 1, sclk_rdiv, sysclk;
+ int tmp;
+ unsigned Multiplier, PreDiv, SysDiv, Pll_rdiv, Bit_div2x = 1;
+ unsigned div, sclk_rdiv, sysclk;
u8 temp;
int sclk_rdiv_map[] = {1, 2, 4, 8};
- temp1 = ov5640_read_reg(0x3034, &temp);
- temp2 = temp1 & 0x0f;
- if (temp2 == 8 || temp2 == 10)
- Bit_div2x = temp2 / 2;
-
- temp1 = ov5640_read_reg(0x3035, &temp);
- SysDiv = temp1>>4;
- if (SysDiv == 0)
+ tmp = ov5640_read_reg(0x3034, &temp);
+ if (tmp < 0)
+ return tmp;
+ tmp &= 0x0f;
+ if (tmp == 8 || tmp == 10)
+ Bit_div2x = tmp / 2;
+
+ tmp = ov5640_read_reg(0x3035, &temp);
+ if (tmp < 0)
+ return tmp;
+ SysDiv = tmp >> 4;
+ if (SysDiv == 0)
SysDiv = 16;
- temp1 = ov5640_read_reg(0x3036, &temp);
- Multiplier = temp1;
-
- temp1 = ov5640_read_reg(0x3037, &temp);
- PreDiv = temp1 & 0x0f;
- Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
-
- temp1 = ov5640_read_reg(0x3108, &temp);
- temp2 = temp1 & 0x03;
- sclk_rdiv = sclk_rdiv_map[temp2];
-
- VCO = xvclk * Multiplier / PreDiv;
-
- sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
-
+ tmp = ov5640_read_reg(0x3036, &temp);
+ if (tmp < 0)
+ return tmp;
+ Multiplier = tmp;
+
+ tmp = ov5640_read_reg(0x3037, &temp);
+ if (tmp < 0)
+ return tmp;
+ PreDiv = tmp & 0x0f;
+ Pll_rdiv = ((tmp >> 4) & 0x01) + 1;
+
+ tmp = ov5640_read_reg(0x3108, &temp);
+ if (tmp < 0)
+ return tmp;
+ sclk_rdiv = sclk_rdiv_map[tmp & 0x03];
+
+ sysclk = ov5640_data.mclk / 10000 * Multiplier;
+ div = PreDiv * SysDiv * Pll_rdiv * Bit_div2x * sclk_rdiv;
+ if (!div) {
+ pr_err("%s:Error divide by 0, (%d * %d * %d * %d * %d)\n",
+ __func__, PreDiv, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv);
+ return -EINVAL;
+ }
+ if (!sysclk) {
+ pr_err("%s:Error 0 clk, ov5640_data.mclk=%d, Multiplier=%d\n",
+ __func__, ov5640_data.mclk, Multiplier);
+ return -EINVAL;
+ }
+ sysclk /= div;
+ pr_debug("%s: sysclk(%d) = %d / 10000 * %d / (%d * %d * %d * %d * %d)\n",
+ __func__, sysclk, ov5640_data.mclk, Multiplier,
+ PreDiv, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv);
return sysclk;
}
@@ -1033,6 +1103,7 @@ static int OV5640_get_light_freq(void)
light_freq = 50;
} else {
/* 60Hz */
+ light_freq = 60;
}
}
return light_freq;
@@ -1125,6 +1196,7 @@ static void ov5640_set_virtual_channel(int channel)
ov5640_read_reg(0x4814, &channel_id);
channel_id &= ~(3 << 6);
ov5640_write_reg(0x4814, channel_id | (channel << 6));
+ pr_info("%s: virtual channel=%d\n", __func__, channel);
}
/* download ov5640 settings to sensor through i2c */
@@ -1416,7 +1488,7 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
OV5640_set_AE_target(AE_Target);
OV5640_get_light_freq();
OV5640_set_bandingfilter();
- ov5640_set_virtual_channel(ov5640_data.csi);
+ ov5640_set_virtual_channel(ov5640_data.csi | (ov5640_data.ipu_id << 1));
/* add delay to wait for sensor stable */
if (mode == ov5640_mode_QSXGA_2592_1944) {
@@ -1433,37 +1505,33 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
msleep(msec_wait4stable);
if (mipi_csi2_info) {
- unsigned int i;
-
- i = 0;
+ unsigned int i = 0;
/* wait for mipi sensor ready */
- mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
- while ((mipi_reg == 0x200) && (i < 10)) {
+ while (1) {
mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
- i++;
+ if (mipi_reg != 0x200)
+ break;
+ if (i++ >= 20) {
+ pr_err("mipi csi2 can not receive sensor clk! %x\n", mipi_reg);
+ return -1;
+ }
msleep(10);
}
- if (i >= 10) {
- pr_err("mipi csi2 can not receive sensor clk!\n");
- return -1;
- }
-
i = 0;
-
/* wait for mipi stable */
- mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
- while ((mipi_reg != 0x0) && (i < 10)) {
+ while (1) {
mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
- i++;
+ if (!mipi_reg)
+ break;
+ if (i++ >= 20) {
+ pr_err("mipi csi2 can not receive data correctly!\n");
+ return -1;
+ }
msleep(10);
}
- if (i >= 10) {
- pr_err("mipi csi2 can not reveive data correctly!\n");
- return -1;
- }
}
err:
return retval;
@@ -1985,7 +2053,7 @@ static struct v4l2_int_slave ov5640_slave = {
static struct v4l2_int_device ov5640_int_device = {
.module = THIS_MODULE,
- .name = "ov564x",
+ .name = "ov564x_mipi",
.type = v4l2_int_type_slave,
.u = {
.slave = &ov5640_slave,
@@ -2001,9 +2069,12 @@ static struct v4l2_int_device ov5640_int_device = {
static int ov5640_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct pwm_device *pwm;
struct device *dev = &client->dev;
int retval;
u8 chip_id_high, chip_id_low;
+ struct regmap *gpr;
+ struct sensor_data *sensor = &ov5640_data;
/* request power down pin */
pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
@@ -2013,8 +2084,10 @@ static int ov5640_probe(struct i2c_client *client,
}
retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
"ov5640_mipi_pwdn");
- if (retval < 0)
+ if (retval < 0) {
+ dev_warn(dev, "request of pwn_gpio failed");
return retval;
+ }
/* request reset pin */
rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
@@ -2024,8 +2097,10 @@ static int ov5640_probe(struct i2c_client *client,
}
retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
"ov5640_mipi_reset");
- if (retval < 0)
+ if (retval < 0) {
+ dev_warn(dev, "request of ov5640_mipi_reset failed");
return retval;
+ }
/* Set initial values for the sensor struct. */
memset(&ov5640_data, 0, sizeof(ov5640_data));
@@ -2051,6 +2126,13 @@ static int ov5640_probe(struct i2c_client *client,
return retval;
}
+ retval = of_property_read_u32(dev->of_node, "ipu_id",
+ &sensor->ipu_id);
+ if (retval) {
+ dev_err(dev, "ipu_id missing or invalid\n");
+ return retval;
+ }
+
retval = of_property_read_u32(dev->of_node, "csi_id",
&(ov5640_data.csi));
if (retval) {
@@ -2071,6 +2153,13 @@ static int ov5640_probe(struct i2c_client *client,
ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
ov5640_data.streamcap.timeperframe.numerator = 1;
+ pwm = pwm_get(dev, NULL);
+ if (!IS_ERR(pwm)) {
+ dev_info(dev, "found pwm%d, period=%d\n", pwm->pwm, pwm->state.period);
+ pwm_config(pwm, pwm->state.period >> 1, pwm->state.period);
+ pwm_enable(pwm);
+ }
+
ov5640_power_on(dev);
ov5640_reset();
@@ -2092,12 +2181,31 @@ static int ov5640_probe(struct i2c_client *client,
return -ENODEV;
}
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ if (of_machine_is_compatible("fsl,imx6q")) {
+ if (sensor->csi == sensor->ipu_id) {
+ int mask = sensor->csi ? (1 << 20) : (1 << 19);
+
+ regmap_update_bits(gpr, IOMUXC_GPR1, mask, 0);
+ }
+ } else if (of_machine_is_compatible("fsl,imx6dl")) {
+ int mask = sensor->csi ? (7 << 3) : (7 << 0);
+ int val = sensor->csi ? (3 << 3) : (0 << 0);
+
+ regmap_update_bits(gpr, IOMUXC_GPR13, mask, val);
+ }
+ } else {
+ pr_err("%s: failed to find fsl,imx6q-iomux-gpr regmap\n",
+ __func__);
+ }
+
ov5640_standby(1);
ov5640_int_device.priv = &ov5640_data;
retval = v4l2_int_device_register(&ov5640_int_device);
- clk_disable_unprepare(ov5640_data.sensor_clk);
+// clk_disable_unprepare(ov5640_data.sensor_clk);
pr_info("camera ov5640_mipi is found\n");
return retval;
diff --git a/drivers/media/platform/mxc/capture/ov5640_mipi_nv.c b/drivers/media/platform/mxc/capture/ov5640_mipi_nv.c
new file mode 100644
index 000000000000..c10b6091208a
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640_mipi_nv.c
@@ -0,0 +1,1509 @@
+/*
+ * Copyright (c) 2012-2013 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/delay.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-mediabus.h>
+#include <media/soc_camera.h>
+#include <linux/of_gpio.h>
+
+struct ov5640_reg {
+ u16 addr;
+ u16 val;
+};
+
+#define MIPI_CSI2_SENS_VC0_PAD_SOURCE 0
+#define MIPI_CSI2_SENS_VC1_PAD_SOURCE 1
+#define MIPI_CSI2_SENS_VC2_PAD_SOURCE 2
+#define MIPI_CSI2_SENS_VC3_PAD_SOURCE 3
+#define MIPI_CSI2_SENS_VCX_PADS_NUM 4
+
+#define OV5640_TABLE_WAIT_MS 0
+#define OV5640_TABLE_END 1
+
+/* -> mode_2592x1944 mode_1920x1080 mode_1280x960 mode_640x480 */
+
+/* System and IO Pad Control [0x3000 ~ 0x3052] */
+#define OV5640_SYSTEM_RESET_00 0x3000 /* default 0x30 -> all 0x00 */
+#define OV5640_SYSTEM_RESET_01 0x3001 /* default 0x08 */
+#define OV5640_SYSTEM_RESET_02 0x3002 /* default 0x1c */
+#define OV5640_SYSTEM_RESET_03 0x3003 /* default 0x00 */
+#define OV5640_SYSTEM_CLK_EN_00 0x3004 /* default 0xcf -> all 0xff */
+#define OV5640_SYSTEM_CLK_EN_01 0x3005 /* default 0xf7 */
+#define OV5640_SYSTEM_CLK_EN_02 0x3006 /* default 0xe3 -> all 0xc3 */
+#define OV5640_SYSTEM_CLK_EN_03 0x3007 /* default 0xff */
+#define OV5640_SYSTEM_CTRL 0x3008 /* default 0x02 all -> (0x82, 0x42, 0x02) */
+#define OV5640_CHIP_ID_H 0x300a /* default 0x56 */
+#define OV5640_CHIP_ID_L 0x300b /* default 0x40 */
+#define OV5640_SYSTEM_MIPI_CTRL 0x300e /* default 0x58 -> all 0x45 */
+#define OV5640_IO_CTRL_01 0x3017 /* default 0x00 */
+#define OV5640_IO_CTRL_02 0x3018 /* default 0x00 */
+#define OV5640_SYSTEM_CTRL_2D 0x302d /* default ---- -> all 0x60 !! */
+#define OV5640_SYSTEM_CTRL_2E 0x302e /* default ---- -> all 0x08 !! */
+#define OV5640_SC_PLL_CTRL0 0x3034 /* default 0x1a -> all 0x18 MIPI_MODE */
+#define OV5640_SC_PLL_CTRL1 0x3035 /* default 0x11 -> 0x11 0x11 0x21 0x14 */
+#define OV5640_SC_PLL_CTRL2 0x3036 /* default 0x69 -> 0x7d 0x54 0x70 0x70 */
+#define OV5640_SC_PLL_CTRL3 0x3037 /* default 0x03 -> all 0x13 */
+#define OV5640_SC_PLL_CTRL5 0x3039 /* not use */
+
+#define SYSTEM_CTRL_SRST 0x80 /* Bit[7]: Software reset */
+#define SYSTEM_CTRL_PDOWN 0x40 /* Bit[6]: Software power down */
+#define MIPI_MODE_8BIT 0x08 /* Bit[3:0]: MIPI bit mode - 8-bit mode */
+#define MIPI_MODE_10BIT 0x0a /* Bit[3:0]: MIPI bit mode - 10-bit mode */
+
+/* SCCB Control [0x3100 ~ 0x3108] */
+#define OV5640_SCCB_SYSTEM_CTRL 0x3103 /* default 0x00 -> all 0x03 */
+#define OV5640_SCCB_SCLK 0x3108 /* default 0x16 -> all 0x01 */
+
+/* VCM Control [0x3600 ~ 0x3606] */
+#define OV5640_VCM_DEBUG_MODE_0 0x3600 /* default ---- -> all 0x08 */
+#define OV5640_VCM_DEBUG_MODE_1 0x3601 /* default ---- -> all 0x33 */
+
+/* Timing Control [0x3800 ~ 0x3821] */
+#define OV5640_TIMING_HS_H 0x3800 /* default 0x00 -> 0x00 0x01 0x00 0x00 X_ADDR_ST */
+#define OV5640_TIMING_HS_L 0x3801 /* default 0x00 -> 0x00 0x50 0x00 0x00 */
+#define OV5640_TIMING_VS_H 0x3802 /* default 0x00 -> 0x00 0x01 0x00 0x00 Y_ADDR_ST */
+#define OV5640_TIMING_VS_L 0x3803 /* default 0x00 -> 0x00 0xaa 0x00 0x04 */
+#define OV5640_TIMING_HW_H 0x3804 /* default 0x0a -> 0x0a 0x08 0x0a 0x0a X_ADDR_END */
+#define OV5640_TIMING_HW_L 0x3805 /* default 0x3f -> 0x3f 0xef 0x3f 0x3f 2623 */
+#define OV5640_TIMING_VH_H 0x3806 /* default 0x07 -> 0x07 0x05 0x07 0x07 Y_ADDR_END */
+#define OV5640_TIMING_VH_L 0x3807 /* default 0x9f -> 0x9f 0xf9 0x9f 0x9b */
+#define OV5640_TIMING_DVPHO_H 0x3808 /* default 0x0a -> 0x0a 0x07 0x05 0x02 width[11:8] */
+#define OV5640_TIMING_DVPHO_L 0x3809 /* default 0x20 -> 0x30 0x90 0x18 0x80 width[7:0] */
+#define OV5640_TIMING_DVPVO_H 0x380a /* default 0x07 -> 0x07 0x04 0x03 0x01 height[11:8] */
+#define OV5640_TIMING_DVPVO_L 0x380b /* default 0x98 -> 0x9c 0x48 0xcc 0xe0 height[7:0] */
+#define OV5640_TIMING_HTS_H 0x380c /* default 0x0b -> 0x0b 0x09 0x07 0x07 */
+#define OV5640_TIMING_HTS_L 0x380d /* default 0x1c -> 0x1c 0xc4 0x5e 0x68 */
+#define OV5640_TIMING_VTS_H 0x380e /* default 0x07 -> 0x07 0x04 0x03 0x03 */
+#define OV5640_TIMING_VTS_L 0x380f /* default 0xb0 -> 0xb0 0x60 0xde 0xd8 */
+#define OV5640_TIMING_HOFFSET_H 0x3810 /* default 0x00 */
+#define OV5640_TIMING_HOFFSET_L 0x3811 /* default 0x10 -> 0x08 0x08 0x06 0x10 */
+#define OV5640_TIMING_VOFFSET_H 0x3812 /* default 0x00 */
+#define OV5640_TIMING_VOFFSET_L 0x3813 /* default 0x04 -> 0x02 0x04 0x02 0x06 */
+#define OV5640_TIMING_X_INC 0x3814 /* default 0x11 -> 0x11 0x11 0x31 0x31 */
+#define OV5640_TIMING_Y_INC 0x3815 /* default 0x11 -> 0x11 0x11 0x31 0x31 */
+#define OV5640_TIMING_REG20 0x3820 /* default 0x40 -> 0x40 0x40 0x41 0x41 sensor vflip */
+#define OV5640_TIMING_REG21 0x3821 /* default 0x00 -> 0x06 0x06 0x07 0x07 */
+#define REG20_SENSOR_VFLIP 0x02
+#define REG20_SENSOR_ISP_FLIP 0x04
+#define REG21_BINNING_EN 0x01
+#define REG21_SENSOR_MIRROR 0x02
+#define REG21_ISP_MIRROR 0x04
+
+#define OV5640_ADDR_H(x) ((x >> 8 ) & 0x0f)
+#define OV5640_ADDR_L(x) (x & 0xff)
+#define OV5640_WIDTH_H(x) ((x >> 8 ) & 0x0f)
+#define OV5640_WIDTH_L(x) (x & 0xff)
+#define OV5640_HEIGHT_H(x) ((x >> 8 ) & 0x0f)
+#define OV5640_HEIGHT_L(x) (x & 0xff)
+#define OV5640_HTS_H(x) ((x >> 8 ) & 0x1f)
+#define OV5640_HTS_L(x) (x & 0xff)
+#define OV5640_VTS_H(x) ((x >> 8 ) & 0xff)
+#define OV5640_VTS_L(x) (x & 0xff)
+#define OV5640_H_OFFSET_H(x) ((x >> 8 ) & 0x0F)
+#define OV5640_H_OFFSET_L(x) (x & 0xff)
+#define OV5640_V_OFFSET_H(x) ((x >> 8 ) & 0x03)
+#define OV5640_V_OFFSET_L(x) (x & 0xff)
+
+/* AEC/AGC power down domain control [0x3A00 ~ 0x3A25] */
+#define OV5640_AEC_CTRL_0F 0x3a0f /* default 0x78 -> all 0x30 */
+#define OV5640_AEC_CTRL_10 0x3a10 /* default 0x68 -> all 0x28 */
+#define OV5640_AEC_CTRL_11 0x3a11 /* default 0xd0 -> all 0x60 */
+#define OV5640_AEC_CTRL_1B 0x3a1b /* default 0x78 -> all 0x30 */
+#define OV5640_AEC_CTRL_1E 0x3a1e /* default 0x68 -> all 0x26 */
+#define OV5640_AEC_CTRL_1F 0x3a1f /* default 0x40 -> all 0x14 */
+#define OV5640_AEC_MAX_EXPO60_H 0x3a02 /* default 0x3d -> 0x07 0x04 0x03 0x03 */
+#define OV5640_AEC_MAX_EXPO60_L 0x3a03 /* default 0x80 -> 0xb6 0x60 0xd8 0xd8 */
+#define OV5640_AEC_B50_STEP_H 0x3a08 /* default 0x01 */
+#define OV5640_AEC_B50_STEP_L 0x3a09 /* default 0x27 -> 0x27 0x50 0x27 0x27 */
+#define OV5640_AEC_B60_STEP_H 0x3a0a /* default 0x00 -> 0x00 0x01 0x00 0x00 */
+#define OV5640_AEC_B60_STEP_L 0x3a0b /* default 0xf6 -> 0xf6 0x18 0xf6 0xf6 */
+#define OV5640_AEC_CTRL_0D 0x3a0d /* default 0x08 -> 0x06 0x03 0x03 0x03 */
+#define OV5640_AEC_CTRL_0E 0x3a0e /* default 0x06 -> 0x06 0x04 0x04 0x04 */
+#define OV5640_AEC_CTRL_13 0x3a13 /* default 0x40 -> all 0x43 */
+#define OV5640_AEC_MAX_EXPO_H 0x3a14 /* default 0x0e -> 0x07 0x04 0x03 0x03 */
+#define OV5640_AEC_MAX_EXPO_L 0x3a15 /* default 0x40 -> 0xb0 0xd0 0xd8 0xd8 */
+#define OV5640_AEC_GAIN_CEILING_0 0x3a18 /* default 0x03 -> all 0x00 */
+#define OV5640_AEC_GAIN_CEILING_1 0x3a19 /* default 0xE0 -> all 0xf8 */
+
+/* 50/60Hz detector control [0x3C00 ~ 0x3C1E] */
+#define OV5640_5060_CTRL_01 0x3c01 /* default 0x00 -> all 0x34 */
+#define OV5640_5060_CTRL_04 0x3c04 /* default 0x20 -> all 0x28 */
+#define OV5640_5060_CTRL_05 0x3c05 /* default 0x70 -> all 0x98 */
+
+#define OV5640_5060_THRESHOLD_1_H 0x3c06 /* default 0x00 -> all 0x00 */
+#define OV5640_5060_THRESHOLD_1_L 0x3c07 /* default 0x00 -> all 0x07 0x07 0x07 0x07 0x08 */
+#define OV5640_5060_THRESHOLD_2_H 0x3c08 /* default 0x01 -> all 0x00 */
+#define OV5640_5060_THRESHOLD_2_L 0x3c09 /* default 0x2c -> all 0x1c */
+#define OV5640_5060_SAMPLE_NUM_H 0x3c0a /* default 0x4e -> all 0x9c */
+#define OV5640_5060_SAMPLE_NUM_L 0x3c0b /* default 0x1f -> all 0x40 */
+
+/* BLC Control [0x4000 ~ 0x4033] */
+#define OV5640_BLC_CTRL_01 0x4001 /* default 0x00 -> 0x02 */
+#define OV5640_BLC_CTRL_04 0x4004 /* default 0x08 -> 0x06 0x06 0x02 0x02 */
+
+/* MIPI control [0x4800 ~ 0x4837] */
+#define OV5640_MIPI_CTRL_00 0x4800 /* default 0x04 */
+#define OV5640_MIPI_CTRL_01 0x4801 /* not use */
+#define OV5640_MIPI_CTRL_05 0x4805 /* not use */
+#define OV5640_MIPI_PCLK_PERIOD 0x4837 /* default 0x10 -> 0x0a 0x0a 0x10 0x44 */
+
+/* Format Control [0x4300 ~ 0x430D] */
+#define FMT_CTRL_00 0x4300 /* default 0xF8 -> all 0x32 */
+
+/* Format Control */
+#define FMT_YUV422 0x30
+/* Output sequence */
+#define OFMT_YUYV 0x00
+#define OFMT_YVYU 0x01
+#define OFMT_UYVY 0x02
+#define OFMT_VYUY 0x03
+
+/* ISP Control [0x5000 ~ 0x5063] */
+#define OV5640_ISP_CTRL_00 0x5000 /* default 0x06 -> all 0xa7 */
+#define OV5640_ISP_CTRL_01 0x5001 /* default 0x01 -> 0x83 0x83 0x83 0xa3 */
+#define OV5640_ISP_MUX_CTRL 0x501F /* default 0x00 -> all 0x00 (000: ISP YUV422) */
+#define OV5640_ISP_DEBUG_25 0x5025 /* default ---- -> all 0x00 */
+#define OV5640_ISP_TEST 0x503D /* default 0x00 */
+#define OV5640_ISP_DEBUG_3E 0x503E /* default ---- */
+#define OV5640_ISP_DEBUG_46 0x5046 /* default ---- */
+
+#define ISP_SCALE_DIGITAL 0x80 /* Special digital effect */
+#define ISP_SCALE_EN 0x20 /* Scale enable */
+#define ISP_AUTO_BALANCE_EN 0x01 /* Auto white balance enable */
+#define ISP_COLOR_MATRIX_EN 0x02 /* Color matrix enable */
+#define ISP_TEST_EN 0x80
+#define ISP_TEST_00 0x00 /* 00: Standard eight color bar */
+#define ISP_TEST_01 0x01 /* 01: Gradual change at vertical mode 1 */
+#define ISP_TEST_10 0x02 /* 10: Gradual change at horizontal */
+#define ISP_TEST_11 0x03 /* 11: Gradual change at vertical mode 2 */
+#define ISP_TEST_TRANSPARENT 0x20 /* Transparent */
+#define ISP_TEST_ROLLING 0x40 /* Rolling */
+
+/* AWB Control [0x5180 ~ 0x51D0] */
+#define OV5640_AWB_CTRL_00 0x5180 /* default 0xff */
+#define OV5640_AWB_CTRL_01 0x5181 /* default 0x58 -> all 0xf2 */
+#define OV5640_AWB_CTRL_02 0x5182 /* default 0x11 -> all 0x00 */
+#define OV5640_AWB_CTRL_03 0x5183 /* default 0x90 -> all 0x14 */
+#define OV5640_AWB_CTRL_04 0x5184 /* default 0x25 */
+#define OV5640_AWB_CTRL_05 0x5185 /* default 0x24 */
+#define OV5640_AWB_CTRL_06 0x5186 /* default ---- -> all 0x09 */
+#define OV5640_AWB_CTRL_07 0x5187 /* default ---- -> all 0x09 */
+#define OV5640_AWB_CTRL_08 0x5188 /* default ---- -> all 0x09 */
+#define OV5640_AWB_CTRL_09 0x5189 /* default ---- -> all 0x75 */
+#define OV5640_AWB_CTRL_10 0x518a /* default ---- -> all 0x54 */
+#define OV5640_AWB_CTRL_11 0x518b /* default ---- -> all 0xe0 */
+#define OV5640_AWB_CTRL_12 0x518c /* default ---- -> all 0xb2 */
+#define OV5640_AWB_CTRL_13 0x518d /* default ---- -> all 0x42 */
+#define OV5640_AWB_CTRL_14 0x518e /* default ---- -> all 0x3d */
+#define OV5640_AWB_CTRL_15 0x518f /* default ---- -> all 0x56 */
+#define OV5640_AWB_CTRL_16 0x5190 /* default ---- -> all 0x46 */
+#define OV5640_AWB_CTRL_17 0x5191 /* default 0xff -> all 0xf8 */
+#define OV5640_AWB_CTRL_18 0x5192 /* default 0x00 -> all 0x04 */
+#define OV5640_AWB_CTRL_19 0x5193 /* default 0xf0 -> all 0x70 */
+#define OV5640_AWB_CTRL_20 0x5194 /* default 0xf0 */
+#define OV5640_AWB_CTRL_21 0x5195 /* default 0xf0 */
+#define OV5640_AWB_CTRL_22 0x5196 /* default 0x03 */
+#define OV5640_AWB_CTRL_23 0x5197 /* default 0x02 -> all 0x01 */
+#define OV5640_AWB_CTRL_24 0x5198 /* default ---- -> all 0x04 */
+#define OV5640_AWB_CTRL_25 0x5199 /* default ---- -> all 0x12 */
+#define OV5640_AWB_CTRL_26 0x519a /* default ---- -> all 0x04 */
+#define OV5640_AWB_CTRL_27 0x519b /* default ---- -> all 0x00 */
+#define OV5640_AWB_CTRL_28 0x519c /* default ---- -> all 0x06 */
+#define OV5640_AWB_CTRL_29 0x519d /* default ---- -> all 0x82 */
+#define OV5640_AWB_CTRL_30 0x519e /* default 0x02 -> all 0x38 */
+
+/* CIP Control [0x5300 ~ 0x530F] */
+#define OV5640_CIP_SH_MT_THRES_1 0x5300 /* default 0x08 */
+#define OV5640_CIP_SH_MT_THRES_2 0x5301 /* default 0x48 -> all 0x30 */
+#define OV5640_CIP_SH_MT_OFFSET_1 0x5302 /* default 0x18 -> all 0x10 */
+#define OV5640_CIP_SH_MT_OFFSET_2 0x5303 /* default 0x0e -> all 0x00 */
+#define OV5640_CIP_DNS_THRES_1 0x5304 /* default 0x08 */
+#define OV5640_CIP_DNS_THRES_2 0x5305 /* default 0x48 -> all 0x30 */
+#define OV5640_CIP_DNS_OFFSET_1 0x5306 /* default 0x09 -> all 0x08 */
+#define OV5640_CIP_DNS_OFFSET_2 0x5307 /* default 0x16 */
+#define OV5640_CIP_SH_TH_THRES_1 0x5309 /* default 0x08 */
+#define OV5640_CIP_SH_TH_THRES_2 0x530a /* default 0x48 -> all 0x30 */
+#define OV5640_CIP_SH_TH_OFFSET_1 0x530b /* default 0x04 */
+#define OV5640_CIP_SH_TH_OFFSET_2 0x530c /* default 0x06 */
+
+/* CMX Control [0x5380 ~ 0x538B] */
+#define OV5640_CMX1 0x5381 /* default 0x20 -> all 0x1e */
+#define OV5640_CMX2 0x5382 /* default 0x64 -> all 0x5b */
+#define OV5640_CMX3 0x5383 /* default 0x08 */
+#define OV5640_CMX4 0x5384 /* default 0x30 -> all 0x0a */
+#define OV5640_CMX5 0x5385 /* default 0x80 -> all 0x7e */
+#define OV5640_CMX6 0x5386 /* default 0xc0 -> all 0x88 */
+#define OV5640_CMX7 0x5387 /* default 0xa0 -> all 0x7c */
+#define OV5640_CMX8 0x5388 /* default 0x98 -> all 0x6c */
+#define OV5640_CMX9 0x5389 /* default 0x08 -> all 0x10 */
+#define OV5640_CMX_SIGN_0 0x538A /* default 0x01 */
+#define OV5640_CMX_SIGN_1 0x538B /* default 0x98 */
+
+/* Gamma Control [0x5480 ~ 0x5490] */
+#define OV5640_GAMMA_CTRL_00 0x5480 /* default 0x00 -> all 0x01 */
+#define OV5640_GAMMA_YST_00 0x5481 /* default 0x26 -> all 0x08 */
+#define OV5640_GAMMA_YST_01 0x5482 /* default 0x35 -> all 0x14 */
+
+#define OV5640_GAMMA_YST_02 0x5483 /* default 0x48 -> all 0x28 */
+#define OV5640_GAMMA_YST_03 0x5484 /* default 0x57 -> all 0x51 */
+#define OV5640_GAMMA_YST_04 0x5485 /* default 0x63 -> all 0x65 */
+#define OV5640_GAMMA_YST_05 0x5486 /* default 0x6e -> all 0x71 */
+
+#define OV5640_GAMMA_YST_06 0x5487 /* default 0x77 -> all 0x7d */
+#define OV5640_GAMMA_YST_07 0x5488 /* default 0x80 -> all 0x87 */
+#define OV5640_GAMMA_YST_08 0x5489 /* default 0x88 -> all 0x91 */
+#define OV5640_GAMMA_YST_09 0x548a /* default 0x96 -> all 0x9a */
+#define OV5640_GAMMA_YST_0A 0x548b /* default 0xa3 -> all 0xaa */
+#define OV5640_GAMMA_YST_0B 0x548c /* default 0xaf -> all 0xb8 */
+#define OV5640_GAMMA_YST_0C 0x548d /* default 0xc5 -> all 0xcd */
+#define OV5640_GAMMA_YST_0D 0x548e /* default 0xd7 -> all 0xdd */
+#define OV5640_GAMMA_YST_0E 0x548f /* default 0xe8 -> all 0xea */
+#define OV5640_GAMMA_YST_0F 0x5490 /* default 0x0f -> all 0x1d */
+
+/* SDE Control [0x5580 ~ 0x558C] */
+#define OV5640_SDE_CTRL_0 0x5580 /* default 0x00 -> all 0x02 */
+#define OV5640_SDE_CTRL_3 0x5583 /* default 0x40 */
+#define OV5640_SDE_CTRL_4 0x5584 /* default 0x40 -> all 0x10 */
+#define OV5640_SDE_CTRL_9 0x5589 /* default 0x01 -> all 0x10 */
+#define OV5640_SDE_CTRL_10 0x558a /* default 0x01 -> all 0x00 */
+#define OV5640_SDE_CTRL_11 0x558b /* default 0xff -> all 0xf8 */
+
+/* LENC Control [0x5800 ~ 0x5849] */
+#define OV5640_LENC_GMTRX_00 0x5800 /* default 0x10 -> all 0x23 */
+#define OV5640_LENC_GMTRX_01 0x5801 /* default 0x10 -> all 0x14 */
+#define OV5640_LENC_GMTRX_02 0x5802 /* default 0x10 -> all 0x0f */
+#define OV5640_LENC_GMTRX_03 0x5803 /* default 0x10 -> all 0x0f */
+#define OV5640_LENC_GMTRX_04 0x5804 /* default 0x10 -> all 0x12 */
+#define OV5640_LENC_GMTRX_05 0x5805 /* default 0x10 -> all 0x26 */
+#define OV5640_LENC_GMTRX_10 0x5806 /* default 0x10 -> all 0x0c */
+#define OV5640_LENC_GMTRX_11 0x5807 /* default 0x08 */
+#define OV5640_LENC_GMTRX_12 0x5808 /* default 0x08 -> all 0x05 */
+#define OV5640_LENC_GMTRX_13 0x5809 /* default 0x08 -> all 0x05 */
+#define OV5640_LENC_GMTRX_14 0x580a /* default 0x08 -> all */
+#define OV5640_LENC_GMTRX_15 0x580b /* default 0x10 -> all 0x0d */
+#define OV5640_LENC_GMTRX_20 0x580c /* default 0x10 -> all 0x08 */
+#define OV5640_LENC_GMTRX_21 0x580d /* default 0x08 -> all 0x03 */
+#define OV5640_LENC_GMTRX_22 0x580e /* default 0x00 */
+#define OV5640_LENC_GMTRX_23 0x580f /* default 0x00 */
+#define OV5640_LENC_GMTRX_24 0x5810 /* default 0x08 -> all 0x03 */
+#define OV5640_LENC_GMTRX_25 0x5811 /* default 0x10 -> all 0x09 */
+#define OV5640_LENC_GMTRX_30 0x5812 /* default 0x10 -> all 0x07 */
+#define OV5640_LENC_GMTRX_31 0x5813 /* default 0x08 -> all 0x03 */
+#define OV5640_LENC_GMTRX_32 0x5814 /* default 0x00 */
+#define OV5640_LENC_GMTRX_33 0x5815 /* default 0x00 -> all 0x01 */
+#define OV5640_LENC_GMTRX_34 0x5816 /* default 0x08 -> all 0x03 */
+#define OV5640_LENC_GMTRX_35 0x5817 /* default 0x10 -> all 0x08 */
+#define OV5640_LENC_GMTRX_40 0x5818 /* default 0x10 -> all 0x0d */
+#define OV5640_LENC_GMTRX_41 0x5819 /* default 0x08 */
+#define OV5640_LENC_GMTRX_42 0x581a /* default 0x08 -> all 0x05 */
+#define OV5640_LENC_GMTRX_43 0x581b /* default 0x08 -> all 0x06 */
+#define OV5640_LENC_GMTRX_44 0x581c /* default 0x08 */
+#define OV5640_LENC_GMTRX_45 0x581d /* default 0x10 -> all 0x0e */
+#define OV5640_LENC_GMTRX_50 0x581e /* default 0x10 -> all 0x29 */
+#define OV5640_LENC_GMTRX_51 0x581f /* default 0x10 -> all 0x17 */
+#define OV5640_LENC_GMTRX_52 0x5820 /* default 0x10 -> all 0x11 */
+#define OV5640_LENC_GMTRX_53 0x5821 /* default 0x10 -> all 0x11 */
+#define OV5640_LENC_GMTRX_54 0x5822 /* default 0x10 -> all 0x15 */
+#define OV5640_LENC_GMTRX_55 0x5823 /* default 0x10 -> all 0x28 */
+#define OV5640_LENC_BRMATRX_00 0x5824 /* default 0xaa -> all 0x46 */
+#define OV5640_LENC_BRMATRX_01 0x5825 /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_02 0x5826 /* default 0xaa -> all 0x08 */
+#define OV5640_LENC_BRMATRX_03 0x5827 /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_04 0x5828 /* default 0xaa -> all 0x64 */
+#define OV5640_LENC_BRMATRX_05 0x5829 /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_06 0x582a /* default 0x99 -> all 0x24 */
+#define OV5640_LENC_BRMATRX_07 0x582b /* default 0x99 -> all 0x22 */
+#define OV5640_LENC_BRMATRX_08 0x582c /* default 0x99 -> all 0x24 */
+#define OV5640_LENC_BRMATRX_09 0x582d /* default 0xaa -> all 0x24 */
+#define OV5640_LENC_BRMATRX_20 0x582e /* default 0xaa -> all 0x06 */
+#define OV5640_LENC_BRMATRX_21 0x582f /* default 0x99 -> all 0x22 */
+#define OV5640_LENC_BRMATRX_22 0x5830 /* default 0x88 -> all 0x40 */
+#define OV5640_LENC_BRMATRX_23 0x5831 /* default 0x99 -> all 0x42 */
+#define OV5640_LENC_BRMATRX_24 0x5832 /* default 0xaa -> all 0x24 */
+#define OV5640_LENC_BRMATRX_30 0x5833 /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_31 0x5834 /* default 0x99 -> all 0x24 */
+#define OV5640_LENC_BRMATRX_32 0x5835 /* default 0x99 -> all 0x22 */
+#define OV5640_LENC_BRMATRX_33 0x5836 /* default 0x99 -> all 0x22 */
+#define OV5640_LENC_BRMATRX_34 0x5837 /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_40 0x5838 /* default 0xaa -> all 0x44 */
+#define OV5640_LENC_BRMATRX_41 0x5839 /* default 0xaa -> all 0x24 */
+#define OV5640_LENC_BRMATRX_42 0x583a /* default 0xaa -> all 0x26 */
+#define OV5640_LENC_BRMATRX_43 0x583b /* default 0xaa -> all 0x28 */
+#define OV5640_LENC_BRMATRX_44 0x583c /* default 0xaa -> all 0x42 */
+#define OV5640_LENC_BR_OFFSET 0x583d /* default 0x88 -> all 0xce */
+
+
+static struct ov5640_reg mode_2592x1944[] = {
+ /* PLL Control MIPI bit rate/lane = 672MHz, 16-bit mode.
+ * Output size: 2592x1944 (0, 0) - (2623, 1951),
+ * Line Length = 2844, Frame Length = 1968
+ * Scaling method: full resolution (dummy 16 pixel
+ * horizontal, 8 lines) 2608x1952 with dummy
+ */
+
+ {OV5640_SC_PLL_CTRL0, 0x10 | MIPI_MODE_8BIT },
+ {OV5640_SC_PLL_CTRL1, 0x11},
+ {OV5640_SC_PLL_CTRL2, 0x7d}, /* default 0x69 PLL multipier */
+ {OV5640_SC_PLL_CTRL3, 0x03 | (1<<4) }, /* default 0x03 PLL divided by 2 */
+
+ {OV5640_MIPI_CTRL_00, 0x04},
+ {OV5640_MIPI_PCLK_PERIOD, 0x0a},
+
+ {OV5640_ISP_CTRL_00, 0xa7},
+ {OV5640_ISP_CTRL_01, 0x83},
+ {OV5640_ISP_MUX_CTRL, 0x00},
+
+ /* Timing Control */
+ {OV5640_TIMING_HS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_HS_L, OV5640_ADDR_L(0) },
+ {OV5640_TIMING_VS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_VS_L, OV5640_ADDR_L(0) },
+ {OV5640_TIMING_HW_H, OV5640_ADDR_H(2623) },
+ {OV5640_TIMING_HW_L, OV5640_ADDR_L(2623) },
+ {OV5640_TIMING_VH_H, OV5640_ADDR_H(1951) },
+ {OV5640_TIMING_VH_L, OV5640_ADDR_L(1951) },
+ {OV5640_TIMING_DVPHO_H, OV5640_WIDTH_H(2592) },
+ {OV5640_TIMING_DVPHO_L, OV5640_WIDTH_L(2592) },
+ {OV5640_TIMING_DVPVO_H, OV5640_HEIGHT_H(1944) },
+ {OV5640_TIMING_DVPVO_L, OV5640_HEIGHT_L(1944) },
+ {OV5640_TIMING_HTS_H, OV5640_HTS_H(2844) },
+ {OV5640_TIMING_HTS_L, OV5640_HTS_L(2844) },
+ {OV5640_TIMING_VTS_H, OV5640_VTS_H(1968) },
+ {OV5640_TIMING_VTS_L, OV5640_VTS_L(1968) },
+ {OV5640_TIMING_HOFFSET_H, OV5640_H_OFFSET_H(16) }, // (2623-2592-1)/2
+ {OV5640_TIMING_HOFFSET_L, OV5640_H_OFFSET_L(16) },
+ {OV5640_TIMING_VOFFSET_H, OV5640_V_OFFSET_H(4) }, // (1951-1944-1)/2
+ {OV5640_TIMING_VOFFSET_L, OV5640_V_OFFSET_L(4) },
+ {OV5640_TIMING_X_INC, 0x11},
+ {OV5640_TIMING_Y_INC, 0x11},
+ {OV5640_TIMING_REG20, 0x40},
+ {OV5640_TIMING_REG21, 0},
+
+ /* magic registers */
+ {0x3612, 0x2b},
+ {0x3618, 0x04},
+ {0x3708, 0x64},
+ {0x3709, 0x12},
+ {0x370c, 0x00},
+
+ /* AEC/AGC Power Down Domain Control */
+ {OV5640_AEC_MAX_EXPO60_H, 0x07},
+ {OV5640_AEC_MAX_EXPO60_L, 0xb0},
+ {OV5640_AEC_B50_STEP_H, 0x01},
+ {OV5640_AEC_B50_STEP_L, 0x27},
+ {OV5640_AEC_B60_STEP_H, 0x00},
+ {OV5640_AEC_B60_STEP_L, 0xf6},
+ {OV5640_AEC_CTRL_0E, 0x06},
+ {OV5640_AEC_CTRL_0D, 0x08},
+ {OV5640_AEC_MAX_EXPO_H, 0x07},
+ {OV5640_AEC_MAX_EXPO_L, 0xb0},
+ {OV5640_AEC_CTRL_13, 0x43},
+ {OV5640_AEC_GAIN_CEILING_0, 0x00},
+ {OV5640_AEC_GAIN_CEILING_1, 0xf8},
+ {OV5640_AEC_CTRL_0F, 0x30},
+ {OV5640_AEC_CTRL_10, 0x28},
+ {OV5640_AEC_CTRL_1B, 0x30},
+ {OV5640_AEC_CTRL_1E, 0x26},
+ {OV5640_AEC_CTRL_11, 0x60},
+ {OV5640_AEC_CTRL_1F, 0x14},
+
+ {OV5640_SYSTEM_CTRL, 0x02},
+ {OV5640_TABLE_END, 0x0000}
+};
+
+static struct ov5640_reg mode_1920x1080[] = {
+ /* PLL Control MIPI bit rate/lane = 672MHz, 16-bit mode.
+ * Output size: 1936x1088 (336, 426) - (2287, 1529),
+ * Line Length = 2500, Frame Length = 1120.
+ * Scaling method: cropping from full resolution
+ * 1936x1088 with dummy pixels
+ */
+
+ {OV5640_SC_PLL_CTRL0, 0x10 | MIPI_MODE_8BIT },
+ {OV5640_SC_PLL_CTRL1, 0x11},
+ {OV5640_SC_PLL_CTRL2, 0x54}, /* default 0x69 PLL multipier */
+ {OV5640_SC_PLL_CTRL3, 0x03 | (1<<4) }, /* default 0x03 PLL divided by 2 */
+
+ {OV5640_MIPI_CTRL_00, 0x04},
+ {OV5640_MIPI_PCLK_PERIOD, 0x0a},
+
+ {OV5640_ISP_CTRL_00, 0xa7},
+ {OV5640_ISP_CTRL_01, 0x83},
+ {OV5640_ISP_MUX_CTRL, 0x00},
+
+ /* Timing Control */
+ {OV5640_TIMING_HS_H, OV5640_ADDR_H(336) },
+ {OV5640_TIMING_HS_L, OV5640_ADDR_L(336) },
+ {OV5640_TIMING_VS_H, OV5640_ADDR_H(426) },
+ {OV5640_TIMING_VS_L, OV5640_ADDR_L(426) },
+ {OV5640_TIMING_HW_H, OV5640_ADDR_H(2287) },
+ {OV5640_TIMING_HW_L, OV5640_ADDR_L(2287) },
+ {OV5640_TIMING_VH_H, OV5640_ADDR_H(1529) },
+ {OV5640_TIMING_VH_L, OV5640_ADDR_L(1529) },
+ {OV5640_TIMING_DVPHO_H, OV5640_WIDTH_H(1920) }, //1936
+ {OV5640_TIMING_DVPHO_L, OV5640_WIDTH_L(1920) },
+ {OV5640_TIMING_DVPVO_H, OV5640_HEIGHT_H(1080) }, //1088
+ {OV5640_TIMING_DVPVO_L, OV5640_HEIGHT_L(1080) },
+ {OV5640_TIMING_HTS_H, OV5640_HTS_H(2500) },
+ {OV5640_TIMING_HTS_L, OV5640_HTS_L(2500) },
+ {OV5640_TIMING_VTS_H, OV5640_VTS_H(1120) },
+ {OV5640_TIMING_VTS_L, OV5640_VTS_L(1120) },
+ {OV5640_TIMING_HOFFSET_H, OV5640_H_OFFSET_H(15) }, // (2287-336-1936-1)/2
+ {OV5640_TIMING_HOFFSET_L, OV5640_H_OFFSET_L(15) },
+ {OV5640_TIMING_VOFFSET_H, OV5640_V_OFFSET_H(11) }, // (1529-426-1088-1)/2
+ {OV5640_TIMING_VOFFSET_L, OV5640_V_OFFSET_L(11) },
+ {OV5640_TIMING_X_INC, 0x11},
+ {OV5640_TIMING_Y_INC, 0x11},
+ {OV5640_TIMING_REG20, 0x40},
+ {OV5640_TIMING_REG21, 0},
+
+ /* magic registers */
+ {0x3612, 0x2b},
+ {0x3618, 0x04},
+ {0x3708, 0x64},
+ {0x3709, 0x12},
+ {0x370c, 0x00},
+
+ /* AEC/AGC Power Down Domain Control */
+ {OV5640_AEC_MAX_EXPO60_H, 0x04},
+ {OV5640_AEC_MAX_EXPO60_L, 0x60},
+ {OV5640_AEC_B50_STEP_H, 0x01},
+ {OV5640_AEC_B50_STEP_L, 0x50},
+ {OV5640_AEC_B60_STEP_H, 0x01},
+ {OV5640_AEC_B60_STEP_L, 0x18},
+ {OV5640_AEC_CTRL_0E, 0x03},
+ {OV5640_AEC_CTRL_0D, 0x04},
+ {OV5640_AEC_MAX_EXPO_H, 0x04},
+ {OV5640_AEC_MAX_EXPO_L, 0x60},
+ {OV5640_AEC_CTRL_13, 0x43},
+ {OV5640_AEC_GAIN_CEILING_0, 0x00},
+ {OV5640_AEC_GAIN_CEILING_1, 0xf8},
+ {OV5640_AEC_CTRL_0F, 0x30},
+ {OV5640_AEC_CTRL_10, 0x28},
+ {OV5640_AEC_CTRL_1B, 0x30},
+ {OV5640_AEC_CTRL_1E, 0x26},
+ {OV5640_AEC_CTRL_11, 0x60},
+ {OV5640_AEC_CTRL_1F, 0x14},
+
+ {OV5640_SYSTEM_CTRL, 0x02},
+ {OV5640_TABLE_END, 0x0000}
+};
+
+static struct ov5640_reg mode_1280x960[] = {
+ /* PLL Control MIPI bit rate/lane = 448MHz, 16-bit mode.
+ * Output size: 1304x972 (0, 0) - (2623, 1951),
+ * Line Length = 1886, Frame Length = 990.
+ * Scaling method: subsampling in vertical and horizontal
+ * 1296x968 supports 2x2 binning
+ */
+
+ {OV5640_SC_PLL_CTRL0, 0x10 | MIPI_MODE_8BIT },
+ {OV5640_SC_PLL_CTRL1, 0x21},
+ {OV5640_SC_PLL_CTRL2, 0x70}, /* default 0x69 PLL multipier */
+ {OV5640_SC_PLL_CTRL3, 0x03 | (1<<4) }, /* default 0x03 PLL divided by 2 */
+
+ {OV5640_MIPI_CTRL_00, 0x04},
+ {OV5640_MIPI_PCLK_PERIOD, 0x10},
+
+ {OV5640_ISP_CTRL_00, 0xa7},
+ {OV5640_ISP_CTRL_01, 0x83},
+ {OV5640_ISP_MUX_CTRL, 0x00},
+
+ /* Timing Control */
+ {OV5640_TIMING_HS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_HS_L, OV5640_ADDR_L(0) },
+ {OV5640_TIMING_VS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_VS_L, OV5640_ADDR_L(0) },
+ {OV5640_TIMING_HW_H, OV5640_ADDR_H(2623) },
+ {OV5640_TIMING_HW_L, OV5640_ADDR_L(2623) },
+ {OV5640_TIMING_VH_H, OV5640_ADDR_H(1951) },
+ {OV5640_TIMING_VH_L, OV5640_ADDR_L(1951) },
+ {OV5640_TIMING_DVPHO_H, OV5640_WIDTH_H(1280) },
+ {OV5640_TIMING_DVPHO_L, OV5640_WIDTH_L(1280) },
+ {OV5640_TIMING_DVPVO_H, OV5640_HEIGHT_H(960) },
+ {OV5640_TIMING_DVPVO_L, OV5640_HEIGHT_L(960) },
+ {OV5640_TIMING_HTS_H, OV5640_HTS_H(1886) },
+ {OV5640_TIMING_HTS_L, OV5640_HTS_L(1886) },
+ {OV5640_TIMING_VTS_H, OV5640_VTS_H(990) },
+ {OV5640_TIMING_VTS_L, OV5640_VTS_L(990) },
+ {OV5640_TIMING_HOFFSET_H, OV5640_H_OFFSET_H(31) }, // (2623-0-(1280*2)-1)/2
+ {OV5640_TIMING_HOFFSET_L, OV5640_H_OFFSET_L(31) },
+ {OV5640_TIMING_VOFFSET_H, OV5640_V_OFFSET_H(15) }, // (1951-0-(960*2)-1)/2
+ {OV5640_TIMING_VOFFSET_L, OV5640_V_OFFSET_L(15) },
+ {OV5640_TIMING_X_INC, 0x11 | (3<<4) },
+ {OV5640_TIMING_Y_INC, 0x11 | (3<<4) },
+ {OV5640_TIMING_REG20, 0x40},
+ {OV5640_TIMING_REG21, REG21_BINNING_EN},
+
+ /* magic registers */
+ {0x3612, 0x29},
+ {0x3618, 0x00},
+ {0x3708, 0x62},
+ {0x3709, 0x52},
+ {0x370c, 0x03},
+
+ /* AEC/AGC Power Down Domain Control */
+ {OV5640_AEC_MAX_EXPO60_H, 0x03},
+ {OV5640_AEC_MAX_EXPO60_L, 0xd8},
+ {OV5640_AEC_B50_STEP_H, 0x01},
+ {OV5640_AEC_B50_STEP_L, 0x27},
+ {OV5640_AEC_B60_STEP_H, 0x00},
+ {OV5640_AEC_B60_STEP_L, 0xf6},
+ {OV5640_AEC_CTRL_0E, 0x03},
+ {OV5640_AEC_CTRL_0D, 0x04},
+ {OV5640_AEC_MAX_EXPO_H, 0x03},
+ {OV5640_AEC_MAX_EXPO_L, 0xd8},
+ {OV5640_AEC_CTRL_13, 0x43},
+ {OV5640_AEC_GAIN_CEILING_0, 0x00},
+ {OV5640_AEC_GAIN_CEILING_1, 0xf8},
+ {OV5640_AEC_CTRL_0F, 0x30},
+ {OV5640_AEC_CTRL_10, 0x28},
+ {OV5640_AEC_CTRL_1B, 0x30},
+ {OV5640_AEC_CTRL_1E, 0x26},
+ {OV5640_AEC_CTRL_11, 0x60},
+ {OV5640_AEC_CTRL_1F, 0x14},
+
+ {OV5640_SYSTEM_CTRL, 0x02},
+ {OV5640_TABLE_END, 0x0000}
+};
+
+static struct ov5640_reg mode_640x480[] = {
+ /* PLL Control MIPI bit rate/lane = ?MHz, 16-bit mode.
+ * Output size: 640x480 (0, 4) - (2623, 1951),
+ * Line Length = 1896, Frame Length = 984.
+ * Scaling method: subsampling from 1280x960
+ * 648x484 with dummy
+ * supports 2x2 binning
+ */
+
+ {OV5640_SC_PLL_CTRL0, 0x10 | MIPI_MODE_8BIT },
+ {OV5640_SC_PLL_CTRL1, 0x14},
+ {OV5640_SC_PLL_CTRL2, 0x70}, /* default 0x69 PLL multipier */
+ {OV5640_SC_PLL_CTRL3, 0x03 | (1<<4) }, /* default 0x03 PLL divided by 2 */
+
+ {OV5640_MIPI_CTRL_00, 0x04},
+ {OV5640_MIPI_PCLK_PERIOD, 0x44},
+
+ {OV5640_ISP_CTRL_00, 0xa7},
+ {OV5640_ISP_CTRL_01, 0x83 | ISP_SCALE_EN},
+ {OV5640_ISP_MUX_CTRL, 0x00},
+
+ /* Timing Control */
+ {OV5640_TIMING_HS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_HS_L, OV5640_ADDR_L(0) },
+ {OV5640_TIMING_VS_H, OV5640_ADDR_H(0) },
+ {OV5640_TIMING_VS_L, OV5640_ADDR_L(4) },
+ {OV5640_TIMING_HW_H, OV5640_ADDR_H(2623) },
+ {OV5640_TIMING_HW_L, OV5640_ADDR_L(2623) },
+ {OV5640_TIMING_VH_H, OV5640_ADDR_H(1947) },
+ {OV5640_TIMING_VH_L, OV5640_ADDR_L(1947) },
+ {OV5640_TIMING_DVPHO_H, OV5640_WIDTH_H(640) },
+ {OV5640_TIMING_DVPHO_L, OV5640_WIDTH_L(640) },
+ {OV5640_TIMING_DVPVO_H, OV5640_HEIGHT_H(480) },
+ {OV5640_TIMING_DVPVO_L, OV5640_HEIGHT_L(480) },
+ {OV5640_TIMING_HTS_H, OV5640_HTS_H(1896) },
+ {OV5640_TIMING_HTS_L, OV5640_HTS_L(1896) },
+ {OV5640_TIMING_VTS_H, OV5640_VTS_H(984) },
+ {OV5640_TIMING_VTS_L, OV5640_VTS_L(984) },
+ {OV5640_TIMING_HOFFSET_H, OV5640_H_OFFSET_H(31) }, // (2623-0-(640*2*2)-1)/2
+ {OV5640_TIMING_HOFFSET_L, OV5640_H_OFFSET_L(31) },
+ {OV5640_TIMING_VOFFSET_H, OV5640_V_OFFSET_H(11) }, // (1947-4-(480*2*2)-1)/2
+ {OV5640_TIMING_VOFFSET_L, OV5640_V_OFFSET_L(11) },
+ {OV5640_TIMING_X_INC, 0x11 | (3<<4) },
+ {OV5640_TIMING_Y_INC, 0x11 | (3<<4) },
+ {OV5640_TIMING_REG20, 0x40},
+ {OV5640_TIMING_REG21, REG21_BINNING_EN},
+
+ /* magic registers */
+ {0x3612, 0x29},
+ {0x3618, 0x00},
+ {0x3708, 0x64},
+ {0x3709, 0x52},
+ {0x370c, 0x03},
+
+ /* AEC/AGC Power Down Domain Control */
+ {OV5640_AEC_MAX_EXPO60_H, 0x03},
+ {OV5640_AEC_MAX_EXPO60_L, 0xd8},
+ {OV5640_AEC_B50_STEP_H, 0x01},
+ {OV5640_AEC_B50_STEP_L, 0x27},
+ {OV5640_AEC_B60_STEP_H, 0x00},
+ {OV5640_AEC_B60_STEP_L, 0xf6},
+ {OV5640_AEC_CTRL_0E, 0x03},
+ {OV5640_AEC_CTRL_0D, 0x04},
+ {OV5640_AEC_MAX_EXPO_H, 0x03},
+ {OV5640_AEC_MAX_EXPO_L, 0xd8},
+ {OV5640_AEC_CTRL_13, 0x43},
+ {OV5640_AEC_GAIN_CEILING_0, 0x00},
+ {OV5640_AEC_GAIN_CEILING_1, 0xf8},
+ {OV5640_AEC_CTRL_0F, 0x30},
+ {OV5640_AEC_CTRL_10, 0x28},
+ {OV5640_AEC_CTRL_1B, 0x30},
+ {OV5640_AEC_CTRL_1E, 0x26},
+ {OV5640_AEC_CTRL_11, 0x60},
+ {OV5640_AEC_CTRL_1F, 0x14},
+
+ {OV5640_SYSTEM_CTRL, 0x02},
+ {OV5640_TABLE_END, 0x0000},
+};
+
+static struct ov5640_reg mode_common_registers[] = {
+
+ /* SCCB Control */
+ {OV5640_SCCB_SYSTEM_CTRL, 0x03}, /* Clock from PLL */
+ {OV5640_SCCB_SCLK, 0x01}, /* PCLK = pll_clki, SCLK = pll_clki/2 */
+
+ /* System Control */
+ {OV5640_SYSTEM_CTRL, 0x02 | SYSTEM_CTRL_SRST }, /* Software reset */
+ {OV5640_TABLE_WAIT_MS, 5},
+ {OV5640_SYSTEM_CTRL, 0x02 | SYSTEM_CTRL_PDOWN }, /* Software power down */
+ {OV5640_SYSTEM_RESET_00, 0x00},
+ {OV5640_SYSTEM_RESET_01, 0x00},
+ {OV5640_SYSTEM_RESET_02, 0x1c},
+ {OV5640_SYSTEM_CLK_EN_00, 0xff},
+ {OV5640_SYSTEM_CLK_EN_02, 0xc3},
+ {OV5640_SYSTEM_MIPI_CTRL, 0x45},
+
+ {OV5640_SYSTEM_CTRL_2D, 0x60}, /* magic values */
+ {OV5640_SYSTEM_CTRL_2E, 0x08}, /* magic values */
+
+ /* Format Control */
+ {FMT_CTRL_00, FMT_YUV422 | OFMT_UYVY },
+
+ /* VCM Control */
+/* {OV5640_VCM_DEBUG_MODE_0, 0x08},*/
+/* {OV5640_VCM_DEBUG_MODE_1, 0x33},*/
+
+ /* 50/60Hz detector control */
+ {OV5640_5060_CTRL_01, 0x34},
+ {OV5640_5060_CTRL_04, 0x28},
+ {OV5640_5060_CTRL_05, 0x98},
+ {OV5640_5060_THRESHOLD_1_H, 0x00},
+ {OV5640_5060_THRESHOLD_1_L, 0x07},
+ {OV5640_5060_THRESHOLD_2_H, 0x00},
+ {OV5640_5060_THRESHOLD_2_L, 0x1c},
+ {OV5640_5060_SAMPLE_NUM_H, 0x9c},
+ {OV5640_5060_SAMPLE_NUM_L, 0x40},
+
+ /* BLC Control */
+ {OV5640_BLC_CTRL_01, 0x02},
+ {OV5640_BLC_CTRL_04, 0x06},
+
+ /* AWB Control */
+ {OV5640_AWB_CTRL_00, 0xff},
+ {OV5640_AWB_CTRL_01, 0xf2},
+ {OV5640_AWB_CTRL_02, 0x00},
+ {OV5640_AWB_CTRL_03, 0x14},
+ {OV5640_AWB_CTRL_04, 0x25},
+ {OV5640_AWB_CTRL_05, 0x24},
+ {OV5640_AWB_CTRL_06, 0x09},
+ {OV5640_AWB_CTRL_07, 0x09},
+ {OV5640_AWB_CTRL_08, 0x09},
+ {OV5640_AWB_CTRL_09, 0x75},
+ {OV5640_AWB_CTRL_10, 0x54},
+ {OV5640_AWB_CTRL_11, 0xe0},
+ {OV5640_AWB_CTRL_12, 0xb2},
+ {OV5640_AWB_CTRL_13, 0x42},
+ {OV5640_AWB_CTRL_14, 0x3d},
+ {OV5640_AWB_CTRL_15, 0x56},
+ {OV5640_AWB_CTRL_16, 0x46},
+ {OV5640_AWB_CTRL_17, 0xf8},
+ {OV5640_AWB_CTRL_18, 0x04},
+ {OV5640_AWB_CTRL_19, 0x70},
+ {OV5640_AWB_CTRL_20, 0xf0},
+ {OV5640_AWB_CTRL_21, 0xf0},
+ {OV5640_AWB_CTRL_22, 0x03},
+ {OV5640_AWB_CTRL_23, 0x01},
+ {OV5640_AWB_CTRL_24, 0x04},
+ {OV5640_AWB_CTRL_25, 0x12},
+ {OV5640_AWB_CTRL_26, 0x04},
+ {OV5640_AWB_CTRL_27, 0x00},
+ {OV5640_AWB_CTRL_28, 0x06},
+ {OV5640_AWB_CTRL_29, 0x82},
+ {OV5640_AWB_CTRL_30, 0x38},
+
+ /* CMX Control */
+ {OV5640_CMX1, 0x1e},
+ {OV5640_CMX2, 0x5b},
+ {OV5640_CMX3, 0x08},
+ {OV5640_CMX4, 0x0a},
+ {OV5640_CMX5, 0x7e},
+ {OV5640_CMX6, 0x88},
+ {OV5640_CMX7, 0x7c},
+ {OV5640_CMX8, 0x6c},
+ {OV5640_CMX9, 0x10},
+ {OV5640_CMX_SIGN_0, 0x01},
+ {OV5640_CMX_SIGN_1, 0x98},
+
+ /* CIP Control */
+ {OV5640_CIP_SH_MT_THRES_1, 0x08},
+ {OV5640_CIP_SH_MT_THRES_2, 0x30},
+ {OV5640_CIP_SH_MT_OFFSET_1, 0x10},
+ {OV5640_CIP_SH_MT_OFFSET_2, 0x00},
+ {OV5640_CIP_DNS_THRES_1, 0x08},
+ {OV5640_CIP_DNS_THRES_2, 0x30},
+ {OV5640_CIP_DNS_OFFSET_1, 0x08},
+ {OV5640_CIP_DNS_OFFSET_2, 0x16},
+ {OV5640_CIP_SH_TH_THRES_1, 0x08},
+ {OV5640_CIP_SH_TH_THRES_2, 0x30},
+ {OV5640_CIP_SH_TH_OFFSET_1, 0x04},
+ {OV5640_CIP_SH_TH_OFFSET_2, 0x06},
+
+ /* Gamma Control */
+ {OV5640_GAMMA_CTRL_00, 0x01},
+ {OV5640_GAMMA_YST_00, 0x08},
+ {OV5640_GAMMA_YST_01, 0x14},
+ {OV5640_GAMMA_YST_02, 0x28},
+ {OV5640_GAMMA_YST_03, 0x51},
+ {OV5640_GAMMA_YST_04, 0x65},
+ {OV5640_GAMMA_YST_05, 0x71},
+ {OV5640_GAMMA_YST_06, 0x7d},
+ {OV5640_GAMMA_YST_07, 0x87},
+ {OV5640_GAMMA_YST_08, 0x91},
+ {OV5640_GAMMA_YST_09, 0x9a},
+ {OV5640_GAMMA_YST_0A, 0xaa},
+ {OV5640_GAMMA_YST_0B, 0xb8},
+ {OV5640_GAMMA_YST_0C, 0xcd},
+ {OV5640_GAMMA_YST_0D, 0xdd},
+ {OV5640_GAMMA_YST_0E, 0xea},
+ {OV5640_GAMMA_YST_0F, 0x1d},
+
+ /* SDE Control */
+ {OV5640_SDE_CTRL_0, 0x02},
+ {OV5640_SDE_CTRL_3, 0x40},
+ {OV5640_SDE_CTRL_4, 0x10},
+ {OV5640_SDE_CTRL_9, 0x10},
+ {OV5640_SDE_CTRL_10, 0x00},
+ {OV5640_SDE_CTRL_11, 0xf8},
+
+ /* LENC Control */
+ {OV5640_LENC_GMTRX_00, 0x23},
+ {OV5640_LENC_GMTRX_01, 0x14},
+ {OV5640_LENC_GMTRX_02, 0x0f},
+ {OV5640_LENC_GMTRX_03, 0x0f},
+ {OV5640_LENC_GMTRX_04, 0x12},
+ {OV5640_LENC_GMTRX_05, 0x26},
+ {OV5640_LENC_GMTRX_10, 0x0c},
+ {OV5640_LENC_GMTRX_11, 0x08},
+ {OV5640_LENC_GMTRX_12, 0x05},
+ {OV5640_LENC_GMTRX_13, 0x05},
+ {OV5640_LENC_GMTRX_14, 0x08},
+ {OV5640_LENC_GMTRX_15, 0x0d},
+ {OV5640_LENC_GMTRX_20, 0x08},
+ {OV5640_LENC_GMTRX_21, 0x03},
+ {OV5640_LENC_GMTRX_22, 0x00},
+ {OV5640_LENC_GMTRX_23, 0x00},
+ {OV5640_LENC_GMTRX_24, 0x03},
+ {OV5640_LENC_GMTRX_25, 0x09},
+ {OV5640_LENC_GMTRX_30, 0x07},
+ {OV5640_LENC_GMTRX_31, 0x03},
+ {OV5640_LENC_GMTRX_32, 0x00},
+ {OV5640_LENC_GMTRX_33, 0x01},
+ {OV5640_LENC_GMTRX_34, 0x03},
+ {OV5640_LENC_GMTRX_35, 0x08},
+ {OV5640_LENC_GMTRX_40, 0x0d},
+ {OV5640_LENC_GMTRX_41, 0x08},
+ {OV5640_LENC_GMTRX_42, 0x05},
+ {OV5640_LENC_GMTRX_43, 0x06},
+ {OV5640_LENC_GMTRX_44, 0x08},
+ {OV5640_LENC_GMTRX_45, 0x0e},
+ {OV5640_LENC_GMTRX_50, 0x29},
+ {OV5640_LENC_GMTRX_51, 0x17},
+ {OV5640_LENC_GMTRX_52, 0x11},
+ {OV5640_LENC_GMTRX_53, 0x11},
+ {OV5640_LENC_GMTRX_54, 0x15},
+ {OV5640_LENC_GMTRX_55, 0x28},
+ {OV5640_LENC_BRMATRX_00, 0x46},
+ {OV5640_LENC_BRMATRX_01, 0x26},
+ {OV5640_LENC_BRMATRX_02, 0x08},
+ {OV5640_LENC_BRMATRX_03, 0x26},
+ {OV5640_LENC_BRMATRX_04, 0x64},
+ {OV5640_LENC_BRMATRX_05, 0x26},
+ {OV5640_LENC_BRMATRX_06, 0x24},
+ {OV5640_LENC_BRMATRX_07, 0x22},
+ {OV5640_LENC_BRMATRX_08, 0x24},
+ {OV5640_LENC_BRMATRX_09, 0x24},
+ {OV5640_LENC_BRMATRX_20, 0x06},
+ {OV5640_LENC_BRMATRX_21, 0x22},
+ {OV5640_LENC_BRMATRX_22, 0x40},
+ {OV5640_LENC_BRMATRX_23, 0x42},
+ {OV5640_LENC_BRMATRX_24, 0x24},
+ {OV5640_LENC_BRMATRX_30, 0x26},
+ {OV5640_LENC_BRMATRX_31, 0x24},
+ {OV5640_LENC_BRMATRX_32, 0x22},
+ {OV5640_LENC_BRMATRX_33, 0x22},
+ {OV5640_LENC_BRMATRX_34, 0x26},
+ {OV5640_LENC_BRMATRX_40, 0x44},
+ {OV5640_LENC_BRMATRX_41, 0x24},
+ {OV5640_LENC_BRMATRX_42, 0x26},
+ {OV5640_LENC_BRMATRX_43, 0x28},
+ {OV5640_LENC_BRMATRX_44, 0x42},
+ {OV5640_LENC_BR_OFFSET, 0xce},
+
+ /* magic registers */
+ {0x3620, 0x52},
+ {0x3621, 0xe0},
+ {0x3622, 0x01},
+ {0x3630, 0x36},
+ {0x3631, 0x0e},
+ {0x3632, 0xe2},
+ {0x3633, 0x12},
+ {0x3634, 0x40},
+ {0x3635, 0x13},
+ {0x3636, 0x03},
+ {0x3703, 0x5a},
+ {0x3704, 0xa0},
+ {0x3705, 0x1a},
+ {0x370b, 0x60},
+ {0x3715, 0x78},
+ {0x3717, 0x01},
+ {0x371b, 0x20},
+ {0x3731, 0x12},
+ {0x3901, 0x0a},
+ {0x3905, 0x02},
+ {0x3906, 0x10},
+ {0x471c, 0x50},
+
+ {OV5640_TABLE_END, 0x0000},
+};
+
+enum {
+ OV5640_MODE_640x480,
+ OV5640_MODE_1280x960,
+ OV5640_MODE_1920x1080,
+ OV5640_MODE_2592x1944,
+ OV5640_SIZE_LAST,
+};
+
+static struct ov5640_reg *mode_table[] = {
+ mode_640x480,
+ mode_1280x960,
+ mode_1920x1080,
+ mode_2592x1944,
+};
+
+static int pwn_gpio, rst_gpio;
+static int test_pattern;
+
+module_param(test_pattern, int, 0644);
+
+static struct ov5640_reg tp_cbars[] = {
+ {OV5640_ISP_TEST, ISP_TEST_EN | ISP_TEST_00 | ISP_TEST_TRANSPARENT | ISP_TEST_ROLLING },
+ {OV5640_TABLE_END, 0x0000}
+};
+
+#define to_ov5640(sd) container_of(sd, struct ov5640_priv, subdev)
+
+#define SIZEOF_I2C_TRANSBUF 32
+
+struct ov5640_priv {
+ struct v4l2_subdev subdev;
+ struct media_pad pads[MIPI_CSI2_SENS_VCX_PADS_NUM];
+ struct v4l2_mbus_framefmt mf;
+
+ int ident;
+ u16 chip_id;
+ u8 revision;
+ bool on;
+
+ int mode;
+
+ struct i2c_client *client;
+ u8 i2c_trans_buf[SIZEOF_I2C_TRANSBUF];
+};
+
+static const struct v4l2_frmsize_discrete ov5640_frmsizes[] = {
+ {640, 480},
+ {1280, 960},
+ {1920, 1080},
+ {2592, 1944},
+};
+
+static uint32_t ov5640_codes[] = {
+ MEDIA_BUS_FMT_UYVY8_2X8,
+};
+
+static int ov5640_find_mode(u32 width, u32 height)
+{
+ int i;
+
+ for (i = 0; i < OV5640_SIZE_LAST; i++) {
+ if ((ov5640_frmsizes[i].width >= width) &&
+ (ov5640_frmsizes[i].height >= height))
+ break;
+ }
+
+ /* If not found, select biggest */
+ if (i >= OV5640_SIZE_LAST)
+ i = OV5640_SIZE_LAST - 1;
+
+ return i;
+}
+
+static int ov5640_read_reg(struct i2c_client *client, u16 addr, u8 *val)
+{
+ int err;
+ struct i2c_msg msg[2];
+ unsigned char data[3];
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 2;
+ msg[0].buf = data;
+
+ /* high byte goes out first */
+ data[0] = (u8) (addr >> 8);
+ data[1] = (u8) (addr & 0xff);
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 1;
+ msg[1].buf = data + 2;
+
+ err = i2c_transfer(client->adapter, msg, 2);
+
+ if (err != 2)
+ return -EINVAL;
+
+ *val = data[2];
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov5640_write_reg(struct i2c_client *client, u16 addr, u8 value)
+{
+ int count;
+ struct i2c_msg msg[1];
+ unsigned char data[4];
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data[0] = addr;
+ data[1] = (u8) (addr & 0xff);
+ data[2] = value;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 3;
+ msg[0].buf = data;
+
+ count = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+ if (count == ARRAY_SIZE(msg)) {
+ return 0;
+ }
+ dev_err(&client->dev,
+ "ov5840: i2c transfer failed, addr: %x, value: %02x\n",
+ addr, (u32)value);
+ return -EIO;
+}
+#endif
+
+static int ov5640_write_bulk_reg(struct i2c_client *client, u8 *data, int len)
+{
+ int err;
+ struct i2c_msg msg;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = len;
+ msg.buf = data;
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (err == 1)
+ return 0;
+
+ dev_err(&client->dev, "ov5640: i2c transfer failed at %x\n",
+ (int)data[0] << 8 | data[1]);
+
+ return err;
+}
+
+static int ov5640_write_table(struct ov5640_priv *priv,
+ struct ov5640_reg table[])
+{
+ int err;
+ struct ov5640_reg *next, *n_next;
+ u8 *b_ptr = priv->i2c_trans_buf;
+ unsigned int buf_filled = 0;
+ u16 val;
+
+ for (next = table; next->addr != OV5640_TABLE_END; next++) {
+ if (next->addr == OV5640_TABLE_WAIT_MS) {
+ msleep(next->val);
+ continue;
+ }
+
+ val = next->val;
+
+ if (!buf_filled) {
+ b_ptr = priv->i2c_trans_buf;
+ *b_ptr++ = next->addr >> 8;
+ *b_ptr++ = next->addr & 0xff;
+ buf_filled = 2;
+ }
+ *b_ptr++ = val;
+ buf_filled++;
+
+ n_next = next + 1;
+ if (n_next->addr != OV5640_TABLE_END &&
+ n_next->addr != OV5640_TABLE_WAIT_MS &&
+ buf_filled < SIZEOF_I2C_TRANSBUF &&
+ n_next->addr == next->addr + 1) {
+ continue;
+ }
+
+ err = ov5640_write_bulk_reg(priv->client,
+ priv->i2c_trans_buf, buf_filled);
+ if (err)
+ return err;
+
+ buf_filled = 0;
+ }
+ return 0;
+}
+
+static void ov5640_set_default_fmt(struct ov5640_priv *priv)
+{
+ struct v4l2_mbus_framefmt *mf = &priv->mf;
+
+ mf->width = ov5640_frmsizes[OV5640_MODE_1920x1080].width;
+ mf->height = ov5640_frmsizes[OV5640_MODE_1920x1080].height;
+ mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ mf->field = V4L2_FIELD_NONE;
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+}
+
+/* Start/Stop streaming from the device */
+static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct ov5640_priv *priv = to_ov5640(sd);
+ int ret = 0;
+
+ if (!enable) {
+ ov5640_set_default_fmt(priv);
+ return 0;
+ }
+
+ ret = ov5640_write_table(priv, mode_common_registers);
+ if (ret)
+ return ret;
+
+ ret = ov5640_write_table(priv, mode_table[priv->mode]);
+ if (ret)
+ return ret;
+
+ if (test_pattern == 1) {
+ ret = ov5640_write_table(priv, tp_cbars);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ov5640_try_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ int mode;
+
+ mode = ov5640_find_mode(mf->width, mf->height);
+ mf->width = ov5640_frmsizes[mode].width;
+ mf->height = ov5640_frmsizes[mode].height;
+
+ mf->field = V4L2_FIELD_NONE;
+ mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+
+ return 0;
+}
+
+static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= ARRAY_SIZE(ov5640_codes))
+ return -EINVAL;
+
+ code->code = ov5640_codes[code->index];
+ return 0;
+}
+
+static int ov5640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct ov5640_priv *priv = to_ov5640(sd);
+ struct v4l2_mbus_framefmt *mf = &format->format;
+
+ if (format->pad) {
+ return -EINVAL;
+ }
+
+ memcpy(mf, &priv->mf, sizeof(struct v4l2_mbus_framefmt));
+
+ return 0;
+}
+
+/* set the format we will capture in */
+static int ov5640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ struct ov5640_priv *priv = to_ov5640(sd);
+ int ret;
+
+ ret = ov5640_try_fmt(sd, mf);
+ if (ret < 0)
+ return ret;
+
+ priv->mode = ov5640_find_mode(mf->width, mf->height);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ memcpy(&priv->mf, mf, sizeof(struct v4l2_mbus_framefmt));
+
+ return 0;
+}
+
+static int ov5640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct ov5640_priv *sensor = to_ov5640(sd);
+
+ sensor->on = on;
+
+ return 0;
+}
+
+static int ov5640_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ return 0;
+}
+
+/* Get chip identification */
+static int ov5640_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *id)
+{
+ struct ov5640_priv *priv = to_ov5640(sd);
+
+ id->ident = priv->ident;
+ id->revision = priv->revision;
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov5640_get_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+ u8 val;
+
+ if (reg->reg & ~0xffff)
+ return -EINVAL;
+
+ reg->size = 2;
+
+ ret = ov5640_read_reg(client, reg->reg, &val);
+ if (ret)
+ return ret;
+
+ reg->val = (__u64)val;
+
+ return ret;
+}
+
+static int ov5640_set_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (reg->reg & ~0xffff || reg->val & ~0xff)
+ return -EINVAL;
+
+ return ov5640_write_reg(client, reg->reg, reg->val);
+}
+#endif
+
+static int ov5640_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ return 0;
+}
+
+static int ov5640_set_frame_desc(struct v4l2_subdev *sd,
+ unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ return 0;
+}
+
+static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= OV5640_SIZE_LAST)
+ return -EINVAL;
+
+ fse->min_width = fse->max_width = ov5640_frmsizes[fse->index].width;
+ fse->min_height = fse->max_height = ov5640_frmsizes[fse->index].height;
+
+ return 0;
+}
+
+static int ov5640_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ if (fie->index > 1)
+ return -EINVAL;
+
+ /* Force 30 fps */
+ fie->interval.numerator = 1;
+ fie->interval.denominator = 30;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops ov5640_pad_ops = {
+ .enum_mbus_code = ov5640_enum_mbus_code,
+ .set_fmt = ov5640_set_fmt,
+ .get_fmt = ov5640_get_fmt,
+ .get_frame_desc = ov5640_get_frame_desc,
+ .set_frame_desc = ov5640_set_frame_desc,
+ .enum_frame_size = ov5640_enum_framesizes,
+ .enum_frame_interval = ov5640_enum_frame_interval,
+};
+
+static struct v4l2_subdev_video_ops ov5640_video_ops = {
+ .s_stream = ov5640_s_stream,
+ .querystd = ov5640_querystd,
+};
+
+static struct v4l2_subdev_core_ops ov5640_core_ops = {
+ .g_chip_ident = ov5640_g_chip_ident,
+ .s_power = ov5640_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov5640_get_register,
+ .s_register = ov5640_set_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ov5640_subdev_ops = {
+ .core = &ov5640_core_ops,
+ .video = &ov5640_video_ops,
+ .pad = &ov5640_pad_ops,
+};
+
+int ov5640_link_setup(struct media_entity *entity,
+ const struct media_pad *local,
+ const struct media_pad *remote, u32 flags)
+{
+ return 0;
+}
+
+struct media_entity_operations ov5640_entity_ops = {
+ .link_setup = ov5640_link_setup,
+};
+
+
+static inline void ov5640_power_down(int enable)
+{
+ if (pwn_gpio < 0)
+ return;
+
+ if (!enable)
+ gpio_set_value_cansleep(pwn_gpio, 0);
+ else
+ gpio_set_value_cansleep(pwn_gpio, 1);
+
+ msleep(2);
+}
+
+static void ov5640_reset(void)
+{
+ if (rst_gpio < 0 || pwn_gpio < 0)
+ return;
+
+ /* camera reset */
+ gpio_set_value(rst_gpio, 1);
+
+ /* camera power dowmn */
+ gpio_set_value(pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value(pwn_gpio, 0);
+ msleep(5);
+
+ gpio_set_value(rst_gpio, 1);
+ msleep(5);
+}
+
+/*
+ * i2c_driver function
+ */
+static int ov5640_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct pinctrl *pinctrl;
+ struct device *dev = &client->dev;
+ struct v4l2_subdev *sd;
+ int retval;
+ u8 chip_id_high, chip_id_low;
+
+ struct ov5640_priv *priv;
+
+ priv = devm_kzalloc(&client->dev, sizeof(struct ov5640_priv),
+ GFP_KERNEL);
+ if (!priv) {
+ dev_err(&client->dev, "Failed to allocate private data!\n");
+ return -ENOMEM;
+ }
+
+ /* init using default mode */
+ priv->mode = 2;
+ ov5640_set_default_fmt(priv);
+
+ /* ov5640 pinctrl */
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(dev, "no pin available\n");
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_warn(dev, "no sensor pwdn pin available");
+ } else {
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_mipi_pwdn");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set power pin\n");
+ dev_warn(dev, "retval=%d\n", retval);
+ return retval;
+ }
+ }
+
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio))
+ dev_warn(dev, "no sensor reset pin available");
+ else {
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "ov5640_mipi_reset");
+ if (retval < 0) {
+ dev_warn(dev, "Failed to set reset pin\n");
+ return retval;
+ }
+ }
+
+ priv->client = client;
+
+ ov5640_reset();
+
+ ov5640_power_down(0);
+
+ retval = ov5640_read_reg(client, OV5640_CHIP_ID_H, &chip_id_high);
+ if (retval < 0 || chip_id_high != 0x56) {
+ pr_warning("camera ov5640_mipi is not found\n");
+ return -ENODEV;
+ }
+ retval = ov5640_read_reg(client, OV5640_CHIP_ID_L, &chip_id_low);
+ if (retval < 0 || chip_id_low != 0x40) {
+ pr_warning("camera ov5640_mipi is not found\n");
+ return -ENODEV;
+ }
+
+ sd = &priv->subdev;
+ v4l2_i2c_subdev_init(sd, client, &ov5640_subdev_ops);
+
+ ov5640_s_stream(sd, 1);
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ priv->pads[MIPI_CSI2_SENS_VC0_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ priv->pads[MIPI_CSI2_SENS_VC1_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ priv->pads[MIPI_CSI2_SENS_VC2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ priv->pads[MIPI_CSI2_SENS_VC3_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ retval = media_entity_pads_init(&sd->entity, MIPI_CSI2_SENS_VCX_PADS_NUM,
+ priv->pads);
+ if (retval < 0)
+ return retval;
+
+ sd->entity.ops = &ov5640_entity_ops;
+ retval = v4l2_async_register_subdev(&priv->subdev);
+
+ if (retval < 0)
+ dev_err(&client->dev, "%s--Async register failed, ret=%d\n", __func__, retval);
+
+ pr_info("camera ov5640_mipi is found, ret: %d\n", retval);
+ return retval;
+}
+
+static int ov5640_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static const struct i2c_device_id ov5640_id[] = {
+ {"ov5640_mipi", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ov5640_id);
+
+static struct i2c_driver ov5640_i2c_driver = {
+ .driver = {
+ .name = "ov5640_mipi_nv",
+ },
+ .probe = ov5640_probe,
+ .remove = ov5640_remove,
+ .id_table = ov5640_id,
+};
+
+static int __init ov5640_module_init(void)
+{
+ return i2c_add_driver(&ov5640_i2c_driver);
+}
+
+static void __exit ov5640_module_exit(void)
+{
+ i2c_del_driver(&ov5640_i2c_driver);
+}
+
+module_init(ov5640_module_init);
+module_exit(ov5640_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV5640");
+MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/mxc/capture/tc358743_h2c.c b/drivers/media/platform/mxc/capture/tc358743_h2c.c
new file mode 100644
index 000000000000..8d2e8f7f1ab8
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/tc358743_h2c.c
@@ -0,0 +1,3401 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * Modifyed by: Edison Fernández <edison.fernandez@ridgerun.com>
+ * Added support to use it with Nitrogen6x
+ *
+ * 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/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fsl_devices.h>
+#include <linux/mutex.h>
+#include <linux/mipi_csi2.h>
+#include <linux/pwm.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-int-device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/soc-dapm.h>
+#include <asm/mach-types.h>
+//#include <mach/audmux.h>
+#include <linux/slab.h>
+#include "mxc_v4l2_capture.h"
+
+#define CODEC_CLOCK 16500000
+/* SSI clock sources */
+#define IMX_SSP_SYS_CLK 0
+
+
+#define TC358743_VOLTAGE_ANALOG 2800000
+#define TC358743_VOLTAGE_DIGITAL_CORE 1500000
+#define TC358743_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 30
+#define MAX_FPS 60
+#define DEFAULT_FPS 60
+
+#define TC358743_XCLK_MIN 27000000
+#define TC358743_XCLK_MAX 42000000
+
+#define TC358743_CHIP_ID_HIGH_BYTE 0x0
+#define TC358743_CHIP_ID_LOW_BYTE 0x0
+#define TC3587430_HDMI_DETECT 0x0f //0x10
+
+#define TC_VOLTAGE_ANALOG 2800000
+#define TC_VOLTAGE_DIGITAL_CORE 1500000
+#define TC_VOLTAGE_DIGITAL_IO 1800000
+
+enum tc358743_mode {
+ tc358743_mode_INIT, /*only for sensor init*/
+ tc358743_mode_INIT1, /*only for sensor init*/
+ tc358743_mode_480P_720_480,
+ tc358743_mode_720P_60_1280_720,
+ tc358743_mode_480P_640_480,
+ tc358743_mode_1080P_1920_1080,
+ tc358743_mode_INIT2, /*only for sensor init*/
+ tc358743_mode_INIT3, /*only for sensor init*/
+ tc358743_mode_INIT4, /*only for sensor init*/
+ tc358743_mode_INIT5, /*only for sensor init*/
+ tc358743_mode_INIT6, /*only for sensor init*/
+ tc358743_mode_720P_1280_720,
+ tc358743_mode_MAX ,
+};
+
+enum tc358743_frame_rate {
+ tc358743_60_fps,
+ tc358743_30_fps,
+ tc358743_max_fps
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u32 u32Val;
+ u32 u32Mask;
+ u8 u8Length;
+ u32 u32Delay_ms;
+};
+
+struct tc358743_mode_info {
+ enum tc358743_mode mode;
+ u32 width;
+ u32 height;
+ u32 vformat;
+ u32 fps;
+ u32 lanes;
+ u32 freq;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+ __u32 flags;
+};
+
+static struct delayed_work det_work;
+static struct sensor_data tc358743_data;
+static int pwn_gpio, rst_gpio;
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+
+static u16 hpd_active = 1;
+
+#define DET_WORK_TIMEOUT_DEFAULT 100
+#define DET_WORK_TIMEOUT_DEFERRED 2000
+#define MAX_BOUNCE 5
+
+static DEFINE_MUTEX(access_lock);
+static int det_work_disable = 0;
+static int det_work_timeout = DET_WORK_TIMEOUT_DEFAULT;
+static u32 hdmi_mode = 0, lock = 0, bounce = 0, fps = 0, audio = 2;
+
+static int tc358743_init_mode(enum tc358743_frame_rate frame_rate,
+ enum tc358743_mode mode);
+
+static int tc358743_toggle_hpd(int active);
+
+static void tc_standby(s32 enable)
+{
+ if (gpio_is_valid(pwn_gpio))
+ gpio_set_value(pwn_gpio, enable ? 1 : 0);
+ pr_debug("tc_standby: powerdown=%x, power_gp=0x%x\n", enable, pwn_gpio);
+ msleep(2);
+}
+
+static void tc_reset(void)
+{
+ /* camera reset */
+ gpio_set_value(rst_gpio, 1);
+
+ /* camera power dowmn */
+ if (gpio_is_valid(pwn_gpio)) {
+ gpio_set_value(pwn_gpio, 1);
+ msleep(5);
+
+ gpio_set_value(pwn_gpio, 0);
+ }
+ msleep(5);
+
+ gpio_set_value(rst_gpio, 0);
+ msleep(1);
+
+ gpio_set_value(rst_gpio, 1);
+ msleep(20);
+
+ if (gpio_is_valid(pwn_gpio))
+ gpio_set_value(pwn_gpio, 1);
+}
+
+static int tc_power_on(struct device *dev)
+{
+ int ret = 0;
+
+ io_regulator = devm_regulator_get(dev, "DOVDD");
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ TC_VOLTAGE_DIGITAL_IO,
+ TC_VOLTAGE_DIGITAL_IO);
+ ret = regulator_enable(io_regulator);
+ if (ret) {
+ pr_err("%s:io set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else {
+ pr_err("%s: cannot get io voltage error\n", __func__);
+ io_regulator = NULL;
+ }
+
+ core_regulator = devm_regulator_get(dev, "DVDD");
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ TC_VOLTAGE_DIGITAL_CORE,
+ TC_VOLTAGE_DIGITAL_CORE);
+ ret = regulator_enable(core_regulator);
+ if (ret) {
+ pr_err("%s:core set voltage error\n", __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else {
+ core_regulator = NULL;
+ pr_err("%s: cannot get core voltage error\n", __func__);
+ }
+
+ analog_regulator = devm_regulator_get(dev, "AVDD");
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ TC_VOLTAGE_ANALOG,
+ TC_VOLTAGE_ANALOG);
+ ret = regulator_enable(analog_regulator);
+ if (ret) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ return ret;
+ } else {
+ dev_dbg(dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else {
+ analog_regulator = NULL;
+ pr_err("%s: cannot get analog voltage error\n", __func__);
+ }
+
+ return ret;
+}
+
+static void det_work_enable(int i)
+{
+ mutex_lock(&access_lock);
+ if (i) {
+ det_work_timeout = DET_WORK_TIMEOUT_DEFERRED;
+ schedule_delayed_work(&(det_work), msecs_to_jiffies(det_work_timeout));
+ det_work_disable = 0;
+ } else {
+ det_work_disable = 1;
+ det_work_timeout = DET_WORK_TIMEOUT_DEFERRED;
+ }
+ mutex_unlock(&access_lock);
+ pr_debug("%s: %d %d\n", __func__, det_work_disable, det_work_timeout);
+}
+
+static u8 cHDMIEDID[256] = {
+ /* FIXME! This is the edid that my ASUS HDMI monitor returns */
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x04, 0x69, 0xf3, 0x24, 0xd6, 0x12, 0x00, 0x00,
+ 0x16, 0x16, 0x01, 0x03, 0x80, 0x34, 0x1d, 0x78, 0x2a, 0xc7, 0x20, 0xa4, 0x55, 0x49, 0x99, 0x27,
+ 0x13, 0x50, 0x54, 0xbf, 0xef, 0x00, 0x71, 0x4f, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0xb3, 0x00,
+ 0xd1, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
+ 0x45, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x36, 0x4c,
+ 0x4d, 0x54, 0x46, 0x30, 0x30, 0x34, 0x38, 0x32, 0x32, 0x0a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x37,
+ 0x4b, 0x1e, 0x55, 0x10, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+ 0x00, 0x41, 0x53, 0x55, 0x53, 0x20, 0x56, 0x48, 0x32, 0x34, 0x32, 0x48, 0x0a, 0x20, 0x01, 0x78,
+ 0x02, 0x03, 0x22, 0x71, 0x4f, 0x01, 0x02, 0x03, 0x11, 0x12, 0x13, 0x04, 0x14, 0x05, 0x0e, 0x0f,
+ 0x1d, 0x1e, 0x1f, 0x10, 0x23, 0x09, 0x07, 0x01, 0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0c, 0x00,
+ 0x10, 0x00, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0x09, 0x25,
+ 0x21, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
+ 0x09, 0x25, 0x21, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28,
+ 0x55, 0x40, 0x09, 0x25, 0x21, 0x00, 0x00, 0x1e, 0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20,
+ 0x0c, 0x40, 0x55, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+
+static struct reg_value tc358743_setting_YUV422_2lane_30fps_720P_1280_720_125MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000004, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000040, 0x00000000, 2, 0},
+ {0x0014, 0x00000000, 0x00000000, 2, 0},
+ {0x0016, 0x000005ff, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000402d, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000801, 0x00000000, 4, 0},
+ {0x021c, 0x00000001, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004800, 0x00000000, 4, 0},
+ {0x0228, 0x00000005, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa300be82, 0x00000000, 4, 0},
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0},
+ {0x8512, 0x000000fe, 0x00000000, 1, 0},
+ {0x8514, 0x00000000, 0x00000000, 1, 0},
+ {0x8515, 0x00000000, 0x00000000, 1, 0},
+ {0x8516, 0x00000000, 0x00000000, 1, 0},
+// HDMI Audio RefClk (26 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0},
+ {0x8540, 0x0000008c, 0x00000000, 1, 0},
+ {0x8541, 0x0000000a, 0x00000000, 1, 0},
+ {0x8630, 0x000000b0, 0x00000000, 1, 0},
+ {0x8631, 0x0000001e, 0x00000000, 1, 0},
+ {0x8632, 0x00000004, 0x00000000, 1, 0},
+ {0x8670, 0x00000001, 0x00000000, 1, 0},
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0},
+ {0x8536, 0x00000040, 0x00000000, 1, 0},
+ {0x853f, 0x0000000a, 0x00000000, 1, 0},
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0},
+ {0x85cb, 0x00000001, 0x00000000, 1, 0},
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0},
+// {0x8544, 0x00000000, 0x00000000, 1, 1000},
+// {0x8544, 0x00000001, 0x00000000, 1, 100},
+ {0x8545, 0x00000031, 0x00000000, 1, 0},
+ {0x8546, 0x0000002d, 0x00000000, 1, 0},
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0},
+ {0x8560, 0x00000024, 0x00000000, 1, 0},
+ {0x8563, 0x00000011, 0x00000000, 1, 0},
+ {0x8564, 0x0000000f, 0x00000000, 1, 0},
+// Video settings
+ {0x8573, 0x00000081, 0x00000000, 1, 0},
+ {0x8571, 0x00000002, 0x00000000, 1, 0},
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+// {0x8651, 0x00000003, 0x00000000, 1, 0}, // Inverted LRCK polarity - (Sony) format
+ {0x8652, 0x00000002, 0x00000000, 1, 0}, // Left-justified I2S (Phillips) format
+// {0x8652, 0x00000000, 0x00000000, 1, 0}, // Right-justified (Sony) format
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0},
+ {0x870b, 0x0000002c, 0x00000000, 1, 0},
+ {0x870c, 0x00000053, 0x00000000, 1, 0},
+ {0x870d, 0x00000001, 0x00000000, 1, 0},
+ {0x870e, 0x00000030, 0x00000000, 1, 0},
+ {0x9007, 0x00000010, 0x00000000, 1, 0},
+ {0x854a, 0x00000001, 0x00000000, 1, 0},
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0},
+ };
+
+static struct reg_value tc358743_setting_YUV422_4lane_720P_60fps_1280_720_133Mhz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000004, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0014, 0x0000ffff, 0x00000000, 2, 0},
+ {0x0016, 0x000005ff, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x00004062, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000d00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000701, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000005, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa300be86, 0x00000000, 4, 0},
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0},
+ {0x8512, 0x000000fe, 0x00000000, 1, 0},
+ {0x8514, 0x00000000, 0x00000000, 1, 0},
+ {0x8515, 0x00000000, 0x00000000, 1, 0},
+ {0x8516, 0x00000000, 0x00000000, 1, 0},
+// HDMI Audio RefClk (26 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0},
+ {0x8540, 0x00000a8c, 0x00000000, 1, 0},
+ {0x8630, 0x00041eb0, 0x00000000, 1, 0},
+ {0x8670, 0x00000001, 0x00000000, 1, 0},
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0},
+ {0x8536, 0x00000040, 0x00000000, 1, 0},
+ {0x853f, 0x0000000a, 0x00000000, 1, 0},
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0},
+ {0x8544, 0x00000000, 0x00000000, 1, 0},
+ {0x8545, 0x00000031, 0x00000000, 1, 0},
+ {0x8546, 0x0000002d, 0x00000000, 1, 0},
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0},
+ {0x85cb, 0x00000001, 0x00000000, 1, 0},
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0},
+ {0x8560, 0x00000024, 0x00000000, 1, 0},
+ {0x8563, 0x00000011, 0x00000000, 1, 0},
+ {0x8564, 0x0000000f, 0x00000000, 1, 0},
+// RGB --> YUV Conversion
+// {0x8574, 0x00000000, 0x00000000, 1, 0},
+ {0x8573, 0x00000081, 0x00000000, 1, 0},
+ {0x8571, 0x00000002, 0x00000000, 1, 0},
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+ {0x8652, 0x00000002, 0x00000000, 1, 0},
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0},
+ {0x870b, 0x0000002c, 0x00000000, 1, 0},
+ {0x870c, 0x00000053, 0x00000000, 1, 0},
+ {0x870d, 0x00000001, 0x00000000, 1, 0},
+ {0x870e, 0x00000030, 0x00000000, 1, 0},
+ {0x9007, 0x00000010, 0x00000000, 1, 0},
+ {0x854a, 0x00000001, 0x00000000, 1, 0},
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_2lane_color_bar_1280_720_125MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000405c, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000801, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000006, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x00000007, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a2, 0x00000000, 4, 0},
+// 1280x720 colorbar
+ {0x000a, 0x00000a00, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 128 pixel black - repeat 128 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(128<<16)},
+// 128 pixel blue - repeat 64 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel red - repeat 64 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel pink - repeat 64 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel green - repeat 64 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel light blue - repeat 64 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel yellow - repeat 64 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel white - repeat 64 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(64<<16)},
+// 720 lines
+ {0x7090, 0x000002cf, 0x00000000, 2, 0},
+ {0x7092, 0x00000580, 0x00000000, 2, 0},
+ {0x7094, 0x00000010, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_4lane_color_bar_1280_720_125MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000405c, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000801, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000006, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x0000001F, 0x00000000, 4, 0}, //{0x0234, 0x00000007, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0}, //{0x0500, 0xa30080a2, 0x00000000, 4, 0},
+// 1280x720 colorbar
+ {0x000a, 0x00000a00, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 128 pixel black - repeat 128 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(128<<16)},
+// 128 pixel blue - repeat 64 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel red - repeat 64 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel pink - repeat 64 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel green - repeat 64 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel light blue - repeat 64 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel yellow - repeat 64 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel white - repeat 64 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(64<<16)},
+// 720 lines
+ {0x7090, 0x000002cf, 0x00000000, 2, 0},
+ {0x7092, 0x00000300, 0x00000000, 2, 0}, //{0x7092, 0x00000580, 0x00000000, 2, 0},
+ {0x7094, 0x00000010, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+
+static struct reg_value tc358743_setting_YUV422_4lane_color_bar_1024_720_200MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x00004050, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001800, 0x00000000, 4, 0},
+ {0x0214, 0x00000002, 0x00000000, 4, 0},
+ {0x0218, 0x00001102, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000003, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000007, 0x00000000, 4, 0},
+ {0x022c, 0x00000001, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0},
+// 1280x720 colorbar
+ {0x000a, 0x00000800, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 128 pixel black - repeat 128 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(128<<16)},
+// 128 pixel blue - repeat 64 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel red - repeat 64 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel pink - repeat 64 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel green - repeat 64 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel light blue - repeat 64 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel yellow - repeat 64 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel white - repeat 64 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(64<<16)},
+// 720 lines
+ {0x0020, 0x0000406f, 0x00000000, 2, 100},
+ {0x7090, 0x000002cf, 0x00000000, 2, 0},
+ {0x7092, 0x00000540, 0x00000000, 2, 0},
+ {0x7094, 0x00000010, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_4lane_color_bar_1280_720_300MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x000080c7, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000003, 0x00000000, 4, 0},
+ {0x0218, 0x00001402, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000003, 0x00000000, 4, 0},
+ {0x0224, 0x00004a00, 0x00000000, 4, 0},
+ {0x0228, 0x00000008, 0x00000000, 4, 0},
+ {0x022c, 0x00000002, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0},
+// 1280x720 colorbar
+ {0x000a, 0x00000a00, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 128 pixel black - repeat 128 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(128<<16)},
+// 128 pixel blue - repeat 64 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel red - repeat 64 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel pink - repeat 64 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel green - repeat 64 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel light blue - repeat 64 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel yellow - repeat 64 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel white - repeat 64 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(64<<16)},
+// 720 lines
+ {0x7090, 0x000002cf, 0x00000000, 2, 0},
+ {0x7092, 0x000006b8, 0x00000000, 2, 0},
+ {0x7094, 0x00000010, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_4lane_color_bar_1920_1023_300MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x000080c7, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000003, 0x00000000, 4, 0},
+ {0x0218, 0x00001402, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000003, 0x00000000, 4, 0},
+ {0x0224, 0x00004a00, 0x00000000, 4, 0},
+ {0x0228, 0x00000008, 0x00000000, 4, 0},
+ {0x022c, 0x00000002, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, //non-continuous clock
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0},
+// 1920x1023 colorbar
+ {0x000a, 0x00000f00, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 128 pixel black - repeat 128 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(128<<16)},
+// 128 pixel blue - repeat 64 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel red - repeat 64 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel pink - repeat 64 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel green - repeat 64 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel light blue - repeat 64 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel yellow - repeat 64 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(64<<16)},
+// 128 pixel white - repeat 64 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(64<<16)},
+// 1023 lines
+ {0x7090, 0x000003fe, 0x00000000, 2, 0},
+ {0x7092, 0x000004d8, 0x00000000, 2, 0},
+ {0x7094, 0x0000002d, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_2lane_color_bar_640_480_174MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x00008073, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+// {0x014c, 0x00000000, 0x00000000, 4, 0},
+// {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001200, 0x00000000, 4, 0},
+ {0x0214, 0x00000002, 0x00000000, 4, 0},
+ {0x0218, 0x00000b02, 0x00000000, 4, 0},
+ {0x021c, 0x00000001, 0x00000000, 4, 0},
+ {0x0220, 0x00000103, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000008, 0x00000000, 4, 0},
+ {0x022c, 0x00000002, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000000, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xA3008082, 0x00000000, 4, 0},
+// 640x480 colorbar
+ {0x000a, 0x00000500, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 80 pixel black - repeate 80 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(80<<16)},
+// 80 pixel blue - repeate 40 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel red - repeate 40 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel pink - repeate 40 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel green - repeate 40 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel light blue - repeate 40 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel yellow - repeate 40 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel white - repeate 40 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(40<<16)},
+// 480 lines
+ {0x7090, 0x000001df, 0x00000000, 2, 0},
+ {0x7092, 0x00000898, 0x00000000, 2, 0},
+ {0x7094, 0x00000285, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_2lane_color_bar_640_480_108MHz_cont[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0010, 0x0000001e, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000404F, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001800, 0x00000000, 4, 0},
+ {0x0214, 0x00000002, 0x00000000, 4, 0},
+ {0x0218, 0x00001102, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000003, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000007, 0x00000000, 4, 0},
+ {0x022c, 0x00000001, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xA30080A2, 0x00000000, 4, 0},
+// 640x480 colorbar
+ {0x000a, 0x00000500, 0x00000000, 2, 0},
+ {0x7080, 0x00000082, 0x00000000, 2, 0},
+// 80 pixel black - repeate 80 times
+ {0x7000, 0x0000007f, 0x00000000, 2, (1<<24)|(80<<16)},
+// 80 pixel blue - repeate 40 times
+ {0x7000, 0x000000ff, 0x00000000, 2, 0},
+ {0x7000, 0x00000000, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel red - repeate 40 times
+ {0x7000, 0x00000000, 0x00000000, 2, 0},
+ {0x7000, 0x000000ff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel pink - repeate 40 times
+ {0x7000, 0x00007fff, 0x00000000, 2, 0},
+ {0x7000, 0x00007fff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel green - repeate 40 times
+ {0x7000, 0x00007f00, 0x00000000, 2, 0},
+ {0x7000, 0x00007f00, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel light blue - repeate 40 times
+ {0x7000, 0x0000c0ff, 0x00000000, 2, 0},
+ {0x7000, 0x0000c000, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel yellow - repeate 40 times
+ {0x7000, 0x0000ff00, 0x00000000, 2, 0},
+ {0x7000, 0x0000ffff, 0x00000000, 2, (2<<24)|(40<<16)},
+// 80 pixel white - repeate 40 times
+ {0x7000, 0x0000ff7f, 0x00000000, 2, 0},
+ {0x7000, 0x0000ff7f, 0x00000000, 2, (2<<24)|(40<<16)},
+// 480 lines
+ {0x7090, 0x000001df, 0x00000000, 2, 0},
+ {0x7092, 0x00000700, 0x00000000, 2, 0},
+ {0x7094, 0x00000010, 0x00000000, 2, 0},
+ {0x7080, 0x00000083, 0x00000000, 2, 0},
+};
+
+//480p RGB2YUV442
+static struct reg_value tc358743_setting_YUV422_2lane_60fps_640_480_125Mhz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000004, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000040, 0x00000000, 2, 0},
+// {0x000a, 0x000005a0, 0x00000000, 2, 0},
+// {0x0010, 0x0000001e, 0x00000000, 2, 0},
+ {0x0014, 0x00000000, 0x00000000, 2, 0},
+ {0x0016, 0x000005ff, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000405c, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000d00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000701, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000005, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xA30080A2, 0x00000000, 4, 0},
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0},
+ {0x8512, 0x000000fe, 0x00000000, 1, 0},
+ {0x8514, 0x00000000, 0x00000000, 1, 0},
+ {0x8515, 0x00000000, 0x00000000, 1, 0},
+ {0x8516, 0x00000000, 0x00000000, 1, 0},
+// HDMI Audio RefClk (26 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0},
+ {0x8540, 0x00000a8c, 0x00000000, 1, 0},
+ {0x8630, 0x00041eb0, 0x00000000, 1, 0},
+ {0x8670, 0x00000001, 0x00000000, 1, 0},
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0},
+ {0x8536, 0x00000040, 0x00000000, 1, 0},
+ {0x853f, 0x0000000a, 0x00000000, 1, 0},
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0},
+ {0x8544, 0x00000000, 0x00000000, 1, 100},
+// {0x8544, 0x00000001, 0x00000000, 1, 100},
+ {0x8545, 0x00000031, 0x00000000, 1, 0},
+ {0x8546, 0x0000002d, 0x00000000, 1, 0},
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0},
+ {0x85cb, 0x00000001, 0x00000000, 1, 0},
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0},
+ {0x8560, 0x00000024, 0x00000000, 1, 0},
+ {0x8563, 0x00000011, 0x00000000, 1, 0},
+ {0x8564, 0x0000000f, 0x00000000, 1, 0},
+// RGB --> YUV Conversion
+ {0x8573, 0x00000081, 0x00000000, 1, 0},
+ {0x8571, 0x00000002, 0x00000000, 1, 0},
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+ {0x8652, 0x00000002, 0x00000000, 1, 0},
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0},
+ {0x870b, 0x0000002c, 0x00000000, 1, 0},
+ {0x870c, 0x00000053, 0x00000000, 1, 0},
+ {0x870d, 0x00000001, 0x00000000, 1, 0},
+ {0x870e, 0x00000030, 0x00000000, 1, 0},
+ {0x9007, 0x00000010, 0x00000000, 1, 0},
+ {0x854a, 0x00000001, 0x00000000, 1, 0},
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0},
+ };
+
+//480p RGB2YUV442
+static struct reg_value tc358743_setting_YUV422_2lane_60fps_720_480_125Mhz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000004, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},
+ {0x0006, 0x00000040, 0x00000000, 2, 0},
+ {0x000a, 0x000005a0, 0x00000000, 2, 0},
+// {0x0010, 0x0000001e, 0x00000000, 2, 0},
+ {0x0014, 0x00000000, 0x00000000, 2, 0},
+ {0x0016, 0x000005ff, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x0000405b, 0x00000000, 2, 0},
+ {0x0022, 0x00000613, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00000d00, 0x00000000, 4, 0},
+ {0x0214, 0x00000001, 0x00000000, 4, 0},
+ {0x0218, 0x00000701, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000001, 0x00000000, 4, 0},
+ {0x0224, 0x00004000, 0x00000000, 4, 0},
+ {0x0228, 0x00000005, 0x00000000, 4, 0},
+ {0x022c, 0x00000000, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xA30080A2, 0x00000000, 4, 0},
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0},
+ {0x8512, 0x000000fe, 0x00000000, 1, 0},
+ {0x8514, 0x00000000, 0x00000000, 1, 0},
+ {0x8515, 0x00000000, 0x00000000, 1, 0},
+ {0x8516, 0x00000000, 0x00000000, 1, 0},
+// HDMI Audio RefClk (27 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0},
+ {0x8540, 0x00000a8c, 0x00000000, 1, 0},
+ {0x8630, 0x00041eb0, 0x00000000, 1, 0},
+ {0x8670, 0x00000001, 0x00000000, 1, 0},
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0},
+ {0x8536, 0x00000040, 0x00000000, 1, 0},
+ {0x853f, 0x0000000a, 0x00000000, 1, 0},
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0},
+ {0x8544, 0x00000000, 0x00000000, 1, 100},
+// {0x8544, 0x00000001, 0x00000000, 1, 100},
+ {0x8545, 0x00000031, 0x00000000, 1, 0},
+ {0x8546, 0x0000002d, 0x00000000, 1, 0},
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0},
+ {0x85cb, 0x00000001, 0x00000000, 1, 0},
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0},
+ {0x8560, 0x00000024, 0x00000000, 1, 0},
+ {0x8563, 0x00000011, 0x00000000, 1, 0},
+ {0x8564, 0x0000000f, 0x00000000, 1, 0},
+// RGB --> YUV Conversion
+ {0x8573, 0x00000081, 0x00000000, 1, 0},
+ {0x8571, 0x00000002, 0x00000000, 1, 0},
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+ {0x8652, 0x00000002, 0x00000000, 1, 0},
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0},
+ {0x870b, 0x0000002c, 0x00000000, 1, 0},
+ {0x870c, 0x00000053, 0x00000000, 1, 0},
+ {0x870d, 0x00000001, 0x00000000, 1, 0},
+ {0x870e, 0x00000030, 0x00000000, 1, 0},
+ {0x9007, 0x00000010, 0x00000000, 1, 0},
+ {0x854a, 0x00000001, 0x00000000, 1, 0},
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0},
+ };
+
+static struct reg_value tc358743_setting_YUV422_4lane_1080P_60fps_1920_1080_300MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0},
+ {0x0004, 0x00000084, 0x00000000, 2, 0},
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},//0},
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},//0},
+ {0x0006, 0x00000000, 0x00000000, 2, 0},
+ {0x0014, 0x00000000, 0x00000000, 2, 0},
+ {0x0016, 0x000005ff, 0x00000000, 2, 0},
+// Program CSI Tx PLL
+ {0x0020, 0x000080c7, 0x00000000, 2, 0},
+ {0x0022, 0x00000213, 0x00000000, 2, 0},
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0},
+ {0x0144, 0x00000000, 0x00000000, 4, 0},
+ {0x0148, 0x00000000, 0x00000000, 4, 0},
+ {0x014c, 0x00000000, 0x00000000, 4, 0},
+ {0x0150, 0x00000000, 0x00000000, 4, 0},
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001e00, 0x00000000, 4, 0},
+ {0x0214, 0x00000003, 0x00000000, 4, 0},
+ {0x0218, 0x00001402, 0x00000000, 4, 0},
+ {0x021c, 0x00000000, 0x00000000, 4, 0},
+ {0x0220, 0x00000003, 0x00000000, 4, 0},
+ {0x0224, 0x00004a00, 0x00000000, 4, 0},
+ {0x0228, 0x00000008, 0x00000000, 4, 0},
+ {0x022c, 0x00000002, 0x00000000, 4, 0},
+ {0x0234, 0x0000001f, 0x00000000, 4, 0},
+ {0x0238, 0x00000001, 0x00000000, 4, 0},
+ {0x0204, 0x00000001, 0x00000000, 4, 0},
+ {0x0518, 0x00000001, 0x00000000, 4, 0},
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0},
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0},
+ {0x8512, 0x000000fe, 0x00000000, 1, 0},
+ {0x8514, 0x00000000, 0x00000000, 1, 0},
+ {0x8515, 0x00000000, 0x00000000, 1, 0},
+ {0x8516, 0x00000000, 0x00000000, 1, 0},
+// HDMI Audio RefClk (27 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0},
+ {0x8540, 0x00000a8c, 0x00000000, 1, 0},
+ {0x8630, 0x00041eb0, 0x00000000, 1, 0},
+ {0x8670, 0x00000001, 0x00000000, 1, 0},
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0},
+ {0x8536, 0x00000040, 0x00000000, 1, 0},
+ {0x853f, 0x0000000a, 0x00000000, 1, 0},
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0},
+ {0x8544, 0x00000010, 0x00000000, 1, 100},
+ {0x8545, 0x00000031, 0x00000000, 1, 0},
+ {0x8546, 0x0000002d, 0x00000000, 1, 0},
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0},
+ {0x85cb, 0x00000001, 0x00000000, 1, 0},
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0},
+ {0x8560, 0x00000024, 0x00000000, 1, 0},
+ {0x8563, 0x00000011, 0x00000000, 1, 0},
+ {0x8564, 0x0000000f, 0x00000000, 1, 0},
+// RGB --> YUV Conversion
+ {0x8571, 0x00000002, 0x00000000, 1, 0},
+ {0x8573, 0x00000081, 0x00000000, 1, 0},
+ {0x8576, 0x00000060, 0x00000000, 1, 0},
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+ {0x8652, 0x00000002, 0x00000000, 1, 0},
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0},
+ {0x870b, 0x0000002c, 0x00000000, 1, 0},
+ {0x870c, 0x00000053, 0x00000000, 1, 0},
+ {0x870d, 0x00000001, 0x00000000, 1, 0},
+ {0x870e, 0x00000030, 0x00000000, 1, 0},
+ {0x9007, 0x00000010, 0x00000000, 1, 0},
+ {0x854a, 0x00000001, 0x00000000, 1, 0},
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0},
+};
+
+static struct reg_value tc358743_setting_YUV422_4lane_1080P_30fps_1920_1080_300MHz[] = {
+ {0x7080, 0x00000000, 0x00000000, 2, 0}, // IR control resister
+ {0x0004, 0x00000084, 0x00000000, 2, 0}, // Internal Generated output pattern,Do not send InfoFrame data out to CSI2,Audio output to CSI2-TX i/f,I2C address index increments on every data byte transfer, disable audio and video TX buffers
+ {0x0002, 0x00000f00, 0x00000000, 2, 100},//0}, // Reset devices and set normal operatio (not sleep)
+ {0x0002, 0x00000000, 0x00000000, 2, 1000},//0}, // Clear reset bits
+ {0x0006, 0x000001f8, 0x00000000, 2, 0}, // FIFO level = 1f8 = 504
+ {0x0014, 0x00000000, 0x00000000, 2, 0}, // Clear interrupt status bits
+ {0x0016, 0x000005ff, 0x00000000, 2, 0}, // Mask audio mute, CSI-TX, and the other interrups
+// Program CSI Tx PLL
+ //{0x0020, 0x000080c7, 0x00000000, 2, 0}, // Input divider setting = 0x8 -> Division ratio = (PRD3..0) + 1 = 9, Feedback divider setting = 0xc7 -> Division ratio = (FBD8...0) + 1 = 200
+ {0x0020, 0x000080c7, 0x00000000, 2, 0}, // Input divider setting = 0x8 -> Division ratio = (PRD3..0) + 1 = 9, Feedback divider setting = 0xc7 -> Division ratio = (FBD8...0) + 1 = 200
+ {0x0022, 0x00000213, 0x00000000, 2, 0}, // HSCK frequency = 500MHz – 1GHz HSCK frequency, Loop bandwidth setting = 50% of maximum loop bandwidth (default), REFCLK toggling –> normal operation, REFCLK stops -> no oscillation, Bypass clock = normal operation, clocks switched off (output LOW), PLL Reset normal operation, PLL Enable = PLL on
+// CSI Tx PHY (32-bit Registers)
+ {0x0140, 0x00000000, 0x00000000, 4, 0}, // Clock Lane DPHY Control: Bypass Lane Enable from PPI Layer enable.
+ {0x0144, 0x00000000, 0x00000000, 4, 0}, // Data Lane 0 DPHY Control: Bypass Lane Enable from PPI Layer enable.
+ {0x0148, 0x00000000, 0x00000000, 4, 0}, // Data Lane 1 DPHY Control: Bypass Lane Enable from PPI Layer enable.
+ {0x014c, 0x00000000, 0x00000000, 4, 0}, // Data Lane 2 DPHY Control: Bypass Lane Enable from PPI Layer enable.
+ {0x0150, 0x00000000, 0x00000000, 4, 0}, // Data Lane 3 DPHY Control: Bypass Lane Enable from PPI Layer enable.
+// CSI Tx PPI (32-bit Registers)
+ {0x0210, 0x00001e00, 0x00000000, 4, 0}, // LINEINITCNT: Line Initialization Wait Counter = 0x1e00 = 7680
+ {0x0214, 0x00000003, 0x00000000, 4, 0}, // LPTXTIMECNT: SYSLPTX Timing Generation Counter = 3
+ {0x0218, 0x00001402, 0x00000000, 4, 0}, // TCLK_HEADERCNT: TCLK_ZERO Counter = 0x14 = 20, TCLK_PREPARE Counter = 0x02 = 2
+ {0x021c, 0x00000000, 0x00000000, 4, 0}, // TCLK_TRAILCNT: TCLK_TRAIL Counter = 0
+ {0x0220, 0x00000003, 0x00000000, 4, 0}, // THS_HEADERCNT: THS_ZERO Counter = 0, THS_PREPARE Counter = 3
+ {0x0224, 0x00004a00, 0x00000000, 4, 0}, // TWAKEUP: TWAKEUP Counter = 0x4a00 = 18944
+ {0x0228, 0x00000008, 0x00000000, 4, 0}, // TCLK_POSTCNT: TCLK_POST Counter = 8
+ {0x022c, 0x00000002, 0x00000000, 4, 0}, // THS_TRAILCNT: THS_TRAIL Counter = 2
+ {0x0234, 0x0000001f, 0x00000000, 4, 0}, // HSTXVREGEN: Enable voltage regulators for lanes and clk
+ {0x0238, 0x00000001, 0x00000000, 4, 0}, // TXOPTIONCNTRL: Set Continuous Clock Mode
+ {0x0204, 0x00000001, 0x00000000, 4, 0}, // PPI STARTCNTRL: start PPI function
+ {0x0518, 0x00000001, 0x00000000, 4, 0}, // CSI_START: start
+ {0x0500, 0xa30080a6, 0x00000000, 4, 0}, // CSI Configuration Register: set register 0x040C with data 0x80a6 (CSI MOde, Disables the HTX_TO timer, High-Speed data transfer is performed to Tx, DSCClk Stays in HS mode when Data Lane goes to LP, 4 Data Lanes,The EOT packet is automatically granted at the end of HS transfer then is transmitted)
+// HDMI Interrupt Mask
+ {0x8502, 0x00000001, 0x00000000, 1, 0}, // SYSTEM INTERRUPT: clear DDC power change detection interrupt
+ {0x8512, 0x000000fe, 0x00000000, 1, 0}, // SYS INTERRUPT MASK: DDC power change detection interrupt not masked
+ {0x8514, 0x00000000, 0x00000000, 1, 0}, // PACKET INTERRUPT MASK: unmask all
+ {0x8515, 0x00000000, 0x00000000, 1, 0}, // CBIT INTERRUPT MASK: unmask all
+ {0x8516, 0x00000000, 0x00000000, 1, 0}, // AUDIO INTERRUPT MASK: unmask all
+// HDMI Audio RefClk (27 MHz)
+ {0x8531, 0x00000001, 0x00000000, 1, 0}, // PHY CONTROL0: 27MHz, DDC5V detection operation.
+ {0x8540, 0x00000a8c, 0x00000000, 1, 0}, // SYS FREQ0 Register: 27MHz
+ {0x8630, 0x00041eb0, 0x00000000, 1, 0}, // Audio FS Lock Detect Control: for 27MHz
+ {0x8670, 0x00000001, 0x00000000, 1, 0}, // AUDIO PLL Setting: For REFCLK = 27MHz
+// HDMI PHY
+ {0x8532, 0x00000080, 0x00000000, 1, 0}, //
+ {0x8536, 0x00000040, 0x00000000, 1, 0}, //
+ {0x853f, 0x0000000a, 0x00000000, 1, 0}, //
+// HDMI System
+ {0x8543, 0x00000032, 0x00000000, 1, 0}, // DDC CONTROL: DDC_ACK output terminal H active, DDC5V_active detect delay 200ms
+ {0x8544, 0x00000010, 0x00000000, 1, 100}, // HPD Control Register: HOTPLUG output ON/OFF control mode = DDC5V detection interlock
+ {0x8545, 0x00000031, 0x00000000, 1, 0}, // ANA CONTROL: PLL charge pump setting for Audio = normal, DAC/PLL power ON/OFF setting for Audio = ON
+ {0x8546, 0x0000002d, 0x00000000, 1, 0}, // AVMUTE CONTROL: AVM_CTL = 0x2d
+// EDID
+ {0x85c7, 0x00000001, 0x00000000, 1, 0}, // EDID MODE REGISTER: nternal EDID-RAM & DDC2B mode
+ {0x85cb, 0x00000001, 0x00000000, 1, 0}, // EDID Length REGISTER 2: EDID data size stored in RAM (upper address bits) = 0x1 (Size = 0x100 = 256)
+// HDCP Setting
+ {0x85d1, 0x00000001, 0x00000000, 1, 0}, //
+ {0x8560, 0x00000024, 0x00000000, 1, 0}, // HDCP MODE: HDCP automatic reset when DVI⇔HDMI switched = on, HDCP Line Rekey timing switch = 7clk mode (Data island delay ON), Bcaps[5] KSVINFO_READY(0x8840[5]) auto clear mode = Auto clear using AKSV write
+ {0x8563, 0x00000011, 0x00000000, 1, 0}, //
+ {0x8564, 0x0000000f, 0x00000000, 1, 0}, //
+// RGB --> YUV Conversion
+ {0x8571, 0x00000002, 0x00000000, 1, 0}, //
+ {0x8573, 0x000000c1, 0x00000000, 1, 0}, // VOUT SET2 REGISTER: 422 fixed output, Video Output 422 conversion mode selection 000: During 444 input, 3tap filter; during 422 input, simple decimation, Enable RGB888 to YUV422 Conversion (Fixed Color output)
+ {0x8574, 0x00000008, 0x00000000, 1, 0}, // VOUT SET3 REGISTER (VOUT_SET3): Follow register bit 0x8573[7] setting
+ {0x8576, 0x00000060, 0x00000000, 1, 0}, // VOUT_COLOR: Output Color = 601 YCbCr Limited, Input Pixel Repetition judgment = automatic, Input Pixel Repetition HOST setting = no repetition
+// HDMI Audio In Setting
+ {0x8600, 0x00000000, 0x00000000, 1, 0},
+ {0x8602, 0x000000f3, 0x00000000, 1, 0},
+ {0x8603, 0x00000002, 0x00000000, 1, 0},
+ {0x8604, 0x0000000c, 0x00000000, 1, 0},
+ {0x8606, 0x00000005, 0x00000000, 1, 0},
+ {0x8607, 0x00000000, 0x00000000, 1, 0},
+ {0x8620, 0x00000022, 0x00000000, 1, 0},
+ {0x8640, 0x00000001, 0x00000000, 1, 0},
+ {0x8641, 0x00000065, 0x00000000, 1, 0},
+ {0x8642, 0x00000007, 0x00000000, 1, 0},
+ {0x8652, 0x00000002, 0x00000000, 1, 0},
+ {0x8665, 0x00000010, 0x00000000, 1, 0},
+// InfoFrame Extraction
+ {0x8709, 0x000000ff, 0x00000000, 1, 0}, // PACKET INTERRUPT MODE: all enable
+ {0x870b, 0x0000002c, 0x00000000, 1, 0}, // NO PACKET LIMIT: NO_ACP_LIMIT = 0x2, NO_AVI_LIMIT = 0xC
+ {0x870c, 0x00000053, 0x00000000, 1, 0}, // When VS receive interrupt is detected, VS storage register automatic clear, When ACP receive interrupt is detected, ACP storage register automatic clear, When AVI receive interrupt occurs, judge input video signal with RGB and no Repetition, When AVI receive interrupt is detected, AVI storage register automatic clear.
+ {0x870d, 0x00000001, 0x00000000, 1, 0}, // ERROR PACKET LIMIT: Packet continuing receive error occurrence detection threshold = 1
+ {0x870e, 0x00000030, 0x00000000, 1, 0}, // NO PACKET LIMIT:
+ {0x9007, 0x00000010, 0x00000000, 1, 0}, //
+ {0x854a, 0x00000001, 0x00000000, 1, 0}, // Initialization completed flag
+// Output Control
+ {0x0004, 0x00000cf7, 0x00000000, 2, 0}, // Configuration Control Register: Power Island Normal, I2S/TDM clock are free running, Enable 2 Audio channels, Audio channel number Auto detect by HW, I2S/TDM Data no delay, Select YCbCr422 8-bit (HDMI YCbCr422 12-bit data format), Send InfoFrame data out to CSI2, Audio output to I2S i/f (valid for 2 channel only), I2C address index increments on every data byte transfer, Audio and Video tx buffres enable.
+};
+
+/* list of image formats supported by TCM825X sensor */
+static const struct v4l2_fmtdesc tc358743_formats[] = {
+ {
+ .description = "RGB888 (RGB24)",
+ .pixelformat = V4L2_PIX_FMT_RGB24, /* 24 RGB-8-8-8 */
+ .flags = MIPI_DT_RGB888 // 0x24
+ },
+ {
+ .description = "RAW12 (Y/CbCr 4:2:0)",
+ .pixelformat = V4L2_PIX_FMT_UYVY, /* 12 Y/CbCr 4:2:0 */
+ .flags = MIPI_DT_RAW12 // 0x2c
+ },
+ {
+ .description = "YUV 4:2:2 8-bit",
+ .pixelformat = V4L2_PIX_FMT_YUYV, /* 8 8-bit color */
+ .flags = MIPI_DT_YUV422 // 0x1e /* UYVY... */
+ },
+};
+
+
+static struct tc358743_mode_info tc358743_mode_info_data[2][tc358743_mode_MAX] = {
+ [0][tc358743_mode_720P_60_1280_720] =
+ {tc358743_mode_720P_60_1280_720, 1280, 720, 12, 0, 4, 133,
+ tc358743_setting_YUV422_4lane_720P_60fps_1280_720_133Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_720P_60fps_1280_720_133Mhz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_1080P_1920_1080] =
+ {tc358743_mode_1080P_1920_1080, 1920, 1080, 15, 0x0b, 4, 300,
+ tc358743_setting_YUV422_4lane_1080P_60fps_1920_1080_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_1080P_60fps_1920_1080_300MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT1] =
+ {tc358743_mode_INIT1, 1280, 720, 12, 0, 2, 125,
+ tc358743_setting_YUV422_2lane_color_bar_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_1280_720_125MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT2] =
+ {tc358743_mode_INIT2, 1280, 720, 12, 0, 4, 125,
+ tc358743_setting_YUV422_4lane_color_bar_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1280_720_125MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT] =
+ {tc358743_mode_INIT, 640, 480, 6, 1, 2, 108,
+ tc358743_setting_YUV422_2lane_color_bar_640_480_108MHz_cont,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_640_480_108MHz_cont),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT4] =
+ {tc358743_mode_INIT4, 640, 480, 6, 1, 2, 174,
+ tc358743_setting_YUV422_2lane_color_bar_640_480_174MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_640_480_174MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT3] =
+ {tc358743_mode_INIT3, 1024, 720, 6, 1, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1024_720_200MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1024_720_200MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_720P_1280_720] =
+ {tc358743_mode_720P_1280_720, 1280, 720, 12, (0x3e)<<8|(0x3c), 2, 125,
+ tc358743_setting_YUV422_2lane_30fps_720P_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_30fps_720P_1280_720_125MHz),
+ MIPI_DT_YUV422,
+ },
+ [0][tc358743_mode_480P_720_480] =
+ {tc358743_mode_480P_720_480, 720, 480, 6, (0x02)<<8|(0x00), 2, 125,
+ tc358743_setting_YUV422_2lane_60fps_720_480_125Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_60fps_720_480_125Mhz),
+ MIPI_DT_YUV422,
+ },
+ [0][tc358743_mode_480P_640_480] =
+ {tc358743_mode_480P_640_480, 640, 480, 6, (0x02)<<8|(0x00), 2, 125,
+ tc358743_setting_YUV422_2lane_60fps_640_480_125Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_60fps_640_480_125Mhz),
+ MIPI_DT_YUV422,
+ },
+ [0][tc358743_mode_INIT5] =
+ {tc358743_mode_INIT5, 1280, 720, 12, 0, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1280_720_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1280_720_300MHz),
+ MIPI_DT_YUV422
+ },
+ [0][tc358743_mode_INIT6] =
+ {tc358743_mode_INIT6, 1920, 1023, 15, 0, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1920_1023_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1920_1023_300MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_720P_60_1280_720] =
+ {tc358743_mode_720P_60_1280_720, 1280, 720, 12, 0, 4, 133,
+ tc358743_setting_YUV422_4lane_720P_60fps_1280_720_133Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_720P_60fps_1280_720_133Mhz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_1080P_1920_1080] =
+ {tc358743_mode_1080P_1920_1080, 1920, 1080, 15, 0xa, 4, 300,
+ tc358743_setting_YUV422_4lane_1080P_30fps_1920_1080_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_1080P_30fps_1920_1080_300MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_INIT1] =
+ {tc358743_mode_INIT1, 1280, 720, 12, 0, 2, 125,
+ tc358743_setting_YUV422_2lane_color_bar_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_1280_720_125MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_INIT2] =
+ {tc358743_mode_INIT2, 1280, 720, 12, 0, 4, 125,
+ tc358743_setting_YUV422_4lane_color_bar_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1280_720_125MHz),
+ MIPI_DT_YUV422
+ },
+
+ [1][tc358743_mode_INIT] =
+ {tc358743_mode_INIT, 640, 480, 6, 1, 2, 108,
+ tc358743_setting_YUV422_2lane_color_bar_640_480_108MHz_cont,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_640_480_108MHz_cont),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_INIT4] =
+ {tc358743_mode_INIT4, 640, 480, 6, 1, 2, 174,
+ tc358743_setting_YUV422_2lane_color_bar_640_480_174MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_color_bar_640_480_174MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_INIT3] =
+ {tc358743_mode_INIT3, 1024, 720, 6, 1, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1024_720_200MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1024_720_200MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_720P_1280_720] =
+ {tc358743_mode_720P_1280_720, 1280, 720, 12, (0x3e)<<8|(0x3c), 2, 125,
+ tc358743_setting_YUV422_2lane_30fps_720P_1280_720_125MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_30fps_720P_1280_720_125MHz),
+ MIPI_DT_YUV422,
+ },
+ [1][tc358743_mode_480P_720_480] =
+ {tc358743_mode_480P_720_480, 720, 480, 6, (0x02)<<8|(0x00), 2, 125,
+ tc358743_setting_YUV422_2lane_60fps_720_480_125Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_60fps_720_480_125Mhz),
+ MIPI_DT_YUV422,
+ },
+ [0][tc358743_mode_480P_640_480] =
+ {tc358743_mode_480P_640_480, 640, 480, 1, (0x02)<<8|(0x00), 2, 125,
+ tc358743_setting_YUV422_2lane_60fps_640_480_125Mhz,
+ ARRAY_SIZE(tc358743_setting_YUV422_2lane_60fps_640_480_125Mhz),
+ MIPI_DT_YUV422,
+ },
+ [1][tc358743_mode_INIT5] =
+ {tc358743_mode_INIT5, 1280, 720, 12, 0, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1280_720_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1280_720_300MHz),
+ MIPI_DT_YUV422
+ },
+ [1][tc358743_mode_INIT6] =
+ {tc358743_mode_INIT6, 1920, 1023, 15, 0, 4, 300,
+ tc358743_setting_YUV422_4lane_color_bar_1920_1023_300MHz,
+ ARRAY_SIZE(tc358743_setting_YUV422_4lane_color_bar_1920_1023_300MHz),
+ MIPI_DT_YUV422
+ },
+};
+
+static int tc358743_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int tc358743_remove(struct i2c_client *client);
+
+static s32 tc358743_read_reg(u16 reg, u32 *val);
+static s32 tc358743_write_reg(u16 reg, u32 val, int len);
+
+static const struct i2c_device_id tc358743_id[] = {
+ {"tc358743_mipi", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tc358743_id);
+
+static struct i2c_driver tc358743_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tc358743_mipi",
+ },
+ .probe = tc358743_probe,
+ .remove = tc358743_remove,
+ .id_table = tc358743_id,
+};
+
+struct _reg_size
+{
+ u16 startaddr, endaddr;
+ int size;
+}
+tc358743_read_reg_size [] =
+{
+ {0x0000, 0x005a, 2},
+ {0x0140, 0x0150, 4},
+ {0x0204, 0x0238, 4},
+ {0x040c, 0x0418, 4},
+ {0x044c, 0x0454, 4},
+ {0x0500, 0x0518, 4},
+ {0x0600, 0x06cc, 4},
+ {0x7000, 0x7100, 2},
+ {0x8500, 0x8bff, 1},
+ {0x8c00, 0x8fff, 4},
+ {0x9000, 0x90ff, 1},
+ {0x9100, 0x92ff, 1},
+ {0, 0, 0},
+};
+
+static s32 tc358743_write_reg(u16 reg, u32 val, int len)
+{
+ int i = 0;
+ u32 data = val;
+ u8 au8Buf[6] = {0};
+ int size = 0;
+
+ while (0 != tc358743_read_reg_size[i].startaddr ||
+ 0 != tc358743_read_reg_size[i].endaddr ||
+ 0 != tc358743_read_reg_size[i].size) {
+ if (tc358743_read_reg_size[i].startaddr <= reg
+ && tc358743_read_reg_size[i].endaddr >= reg) {
+ size = tc358743_read_reg_size[i].size;
+ break;
+ }
+ i++;
+ }
+ if (!size) {
+ pr_err("%s:write reg error:reg=%x is not found\n",__func__, reg);
+ return -1;
+ }
+ if (size == 3) {
+ size = 2;
+ } else if (size != len) {
+ pr_err("%s:write reg len error:reg=%x %d instead of %d\n",
+ __func__, reg, len, size);
+ return 0;
+ }
+
+ while (len > 0) {
+ i = 0;
+ au8Buf[i++] = (reg >> 8) & 0xff;
+ au8Buf[i++] = reg & 0xff;
+ while (size-- > 0)
+ {
+ au8Buf[i++] = (u8)data;
+ data >>= 8;
+ }
+
+ if (i2c_master_send(tc358743_data.i2c_client, au8Buf, i) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+ len -= (u8)size;
+ reg += (u16)size;
+ }
+
+ return 0;
+}
+
+static s32 tc358743_read_reg(u16 reg, u32 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u32 u32RdVal = 0;
+ int i=0;
+ int size = 0;
+
+ while (0 != tc358743_read_reg_size[i].startaddr ||
+ 0 != tc358743_read_reg_size[i].endaddr ||
+ 0 != tc358743_read_reg_size[i].size) {
+ if (tc358743_read_reg_size[i].startaddr <= reg &&
+ tc358743_read_reg_size[i].endaddr >= reg) {
+ size = tc358743_read_reg_size[i].size;
+ break;
+ }
+ i++;
+ }
+ if (!size)
+ return -1;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(tc358743_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:read reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (size /*of(u32RdVal)*/ != i2c_master_recv(tc358743_data.i2c_client, (char *)&u32RdVal, size /*of(u32RdVal)*/)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u32RdVal);
+ return -1;
+ }
+ *val = u32RdVal;
+ return size;
+}
+
+static int tc358743_write_edid(u8 *edid, int len)
+{
+ int i = 0, off = 0;
+ u8 au8Buf[8+2] = {0};
+ int size = 0;
+ u16 reg;
+
+ reg = 0x8C00;
+ off = 0;
+ size = ARRAY_SIZE(au8Buf)-2;
+ pr_debug("Write EDID: %d (%d)\n", len, size);
+ while (len > 0) {
+ i = 0;
+ au8Buf[i++] = (reg >> 8) & 0xff;
+ au8Buf[i++] = reg & 0xff;
+ while (i < ARRAY_SIZE(au8Buf)) {
+ au8Buf[i++] = edid[off++];
+ }
+
+ if (i2c_master_send(tc358743_data.i2c_client, au8Buf, i) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, off);
+ return -1;
+ }
+ len -= (u8)size;
+ reg += (u16)size;
+ }
+ pr_debug("Activate EDID\n");
+ tc358743_write_reg(0x85c7, 0x01, 1);
+ tc358743_write_reg(0x85ca, 0x00, 1);
+ tc358743_write_reg(0x85cb, 0x01, 1);
+ return 0;
+}
+
+static int tc358743_reset(struct sensor_data *sensor)
+{
+ u32 tgt_fps; /* target frames per secound */
+ enum tc358743_frame_rate frame_rate = tc358743_60_fps;
+ int ret = -1;
+
+ det_work_enable(0);
+ while (ret) {
+ tc_standby(1);
+ mdelay(100);
+ tc_standby(0);
+ mdelay(1000);
+
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 60)
+ frame_rate = tc358743_60_fps;
+ else if (tgt_fps == 30)
+ frame_rate = tc358743_30_fps;
+
+ pr_debug("%s: capture mode: %d extended mode: %d fps: %d\n", __func__,sensor->streamcap.capturemode, sensor->streamcap.extendedmode, tgt_fps);
+
+ ret = tc358743_init_mode(frame_rate,
+ sensor->streamcap.capturemode);
+ if (ret)
+ pr_err("%s: Fail to init tc35874! - retry\n", __func__);
+ }
+ det_work_enable(1);
+ return ret;
+}
+
+void mipi_csi2_swreset(struct mipi_csi2_info *info);
+#include "../../../../mxc/mipi/mxc_mipi_csi2.h"
+static int tc358743_init_mode(enum tc358743_frame_rate frame_rate,
+ enum tc358743_mode mode)
+{
+
+ struct reg_value *pModeSetting = NULL;
+ s32 i = 0;
+ s32 iModeSettingArySize = 0;
+ register u32 RepeateLines = 0;
+ register int RepeateTimes = 0;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u32 Mask = 0;
+ register u32 Val = 0;
+ u8 Length;
+ u32 RegVal = 0;
+ int retval = 0;
+ void *mipi_csi2_info;
+ u32 mipi_reg;
+ u32 mipi_reg_test[10];
+
+ pr_debug("%s rate: %d mode: %d\n", __func__, frame_rate, mode);
+ if ((mode > tc358743_mode_MAX || mode < 0)
+ && (mode != tc358743_mode_INIT)) {
+ pr_debug("%s Wrong tc358743 mode detected! %d. Set mode 0\n", __func__, mode);
+ mode = 0;
+ }
+
+ mipi_csi2_info = mipi_csi2_get_info();
+ pr_debug("%s rate: %d mode: %d, info %p\n", __func__, frame_rate, mode, mipi_csi2_info);
+
+ /* initial mipi dphy */
+ tc358743_toggle_hpd(!hpd_active);
+ if (mipi_csi2_info) {
+ pr_debug("%s: mipi_csi2_info:\n"
+ "mipi_en: %d\n"
+ "ipu_id: %d\n"
+ "csi_id: %d\n"
+ "v_channel: %d\n"
+ "lanes: %d\n"
+ "datatype: %d\n"
+ "dphy_clk: %p\n"
+ "pixel_clk: %p\n"
+ "mipi_csi2_base:%p\n"
+ "pdev: %p\n"
+ , __func__,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->mipi_en,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->ipu_id,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->csi_id,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->v_channel,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->lanes,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->datatype,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->dphy_clk,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->pixel_clk,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->mipi_csi2_base,
+ ((struct mipi_csi2_info *)mipi_csi2_info)->pdev
+ );
+ if (!mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_enable(mipi_csi2_info);
+
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ int ifmt;
+ if (tc358743_mode_info_data[frame_rate][mode].lanes != 0) {
+ pr_debug("%s Change lanes: from %d to %d\n", __func__, ((struct mipi_csi2_info *)mipi_csi2_info)->lanes, tc358743_mode_info_data[frame_rate][mode].lanes);
+ ((struct mipi_csi2_info *)mipi_csi2_info)->lanes = tc358743_mode_info_data[frame_rate][mode].lanes;
+ ((struct mipi_csi2_info *)mipi_csi2_info)->lanes = tc358743_mode_info_data[frame_rate][mode].lanes;
+ }
+ pr_debug("Now Using %d lanes\n",mipi_csi2_set_lanes(mipi_csi2_info));
+
+ /*Only reset MIPI CSI2 HW at sensor initialize*/
+ if (!hdmi_mode) // is this during reset
+ mipi_csi2_reset(mipi_csi2_info);
+
+
+ pr_debug("%s format: %x\n", __func__, tc358743_data.pix.pixelformat);
+ for (ifmt = 0; ifmt < ARRAY_SIZE(tc358743_formats); ifmt++)
+ if (tc358743_mode_info_data[frame_rate][mode].flags == tc358743_formats[ifmt].flags) {
+ tc358743_data.pix.pixelformat = tc358743_formats[ifmt].pixelformat;
+ pr_debug("%s: %s (%x, %x)\n", __func__, tc358743_formats[ifmt].description, tc358743_data.pix.pixelformat, tc358743_formats[ifmt].flags);
+ mipi_csi2_set_datatype(mipi_csi2_info, tc358743_formats[ifmt].flags);
+ break;
+ }
+ if (ifmt >= ARRAY_SIZE(tc358743_formats)) {
+ pr_err("currently this sensor format (0x%x) can not be supported!\n", tc358743_data.pix.pixelformat);
+ return -1;
+ }
+ } else {
+ pr_err("Can not enable mipi csi2 driver!\n");
+ return -1;
+ }
+ } else {
+ pr_err("Fail to get mipi_csi2_info!\n");
+ return -1;
+ }
+
+ {
+ pModeSetting =
+ tc358743_mode_info_data[frame_rate][mode].init_data_ptr;
+ iModeSettingArySize =
+ tc358743_mode_info_data[frame_rate][mode].init_data_size;
+
+ tc358743_data.pix.width =
+ tc358743_mode_info_data[frame_rate][mode].width;
+ tc358743_data.pix.height =
+ tc358743_mode_info_data[frame_rate][mode].height;
+ pr_debug("%s: Set %d regs from %p for frs %d mode %d with width %d height %d\n", __func__,
+ iModeSettingArySize,
+ pModeSetting,
+ frame_rate,
+ mode,
+ tc358743_data.pix.width,
+ tc358743_data.pix.height);
+ for (i = 0; i < iModeSettingArySize; ++i) {
+ pModeSetting = tc358743_mode_info_data[frame_rate][mode].init_data_ptr + i;
+
+ Delay_ms = pModeSetting->u32Delay_ms & (0xffff);
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u32Val;
+ Mask = pModeSetting->u32Mask;
+ Length = pModeSetting->u8Length;
+ if (Mask) {
+ retval = tc358743_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ break;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = tc358743_write_reg(RegAddr, Val, Length);
+ if (retval < 0)
+ break;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+
+ if (0 != ((pModeSetting->u32Delay_ms>>16) & (0xff))) {
+ if (!RepeateTimes) {
+ RepeateTimes = (pModeSetting->u32Delay_ms>>16) & (0xff);
+ RepeateLines = (pModeSetting->u32Delay_ms>>24) & (0xff);
+ }
+ if (--RepeateTimes > 0) {
+ i -= RepeateLines;
+ }
+ }
+ }
+ if (retval < 0) {
+ pr_err("%s: Fail to write REGS to tc35874!\n", __func__);
+ goto err;
+ }
+ }
+ if (!hdmi_mode) // is this during reset
+ if ((retval = tc358743_write_edid(cHDMIEDID, ARRAY_SIZE(cHDMIEDID))))
+ pr_err("%s: Fail to write EDID to tc35874!\n", __func__);
+
+ tc358743_toggle_hpd(hpd_active);
+ if (mipi_csi2_info) {
+ unsigned int i = 0;
+
+ /* wait for mipi sensor ready */
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ while ((mipi_reg == 0x200) && (i < 10)) {
+ mipi_reg_test[i] = mipi_reg;
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not receive sensor clk!\n");
+ return -1;
+ }
+
+ {
+ int j;
+ for (j = 0; j < i; j++)
+ {
+ pr_debug("%d mipi csi2 dphy status %x\n", j, mipi_reg_test[j]);
+ }
+ }
+
+ i = 0;
+
+ /* wait for mipi stable */
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ while ((mipi_reg != 0x0) && (i < 10)) {
+ mipi_reg_test[i] = mipi_reg;
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not reveive data correctly!\n");
+ return -1;
+ }
+
+ {
+ int j;
+ for (j = 0; j < i; j++) {
+ pr_debug("%d mipi csi2 err1 %x\n", j, mipi_reg_test[j]);
+ }
+ }
+ }
+err:
+ return (retval>0)?0:retval;
+}
+
+/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ pr_debug("%s\n", __func__);
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->u.bt656.clock_curr = TC358743_XCLK_MIN; //tc358743_data.mclk;
+ pr_debug("%s: clock_curr=mclk=%d\n", __func__, tc358743_data.mclk);
+ p->if_type = V4L2_IF_TYPE_BT656;
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.clock_min = TC358743_XCLK_MIN;
+ p->u.bt656.clock_max = TC358743_XCLK_MAX;
+ p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor_data *sensor = s->priv;
+
+ pr_debug("%s: %d\n", __func__, on);
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ /* Make sure power on */
+ tc_standby(0);
+
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+ if (!hdmi_mode)
+ tc358743_reset(sensor);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ pr_debug("%s type: %x\n", __func__, a->type);
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ cparm->extendedmode = sensor->streamcap.extendedmode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ det_work_enable(1);
+ pr_debug("%s done %d\n", __func__, ret);
+ return ret;
+}
+
+static int tc358743_toggle_hpd(int active)
+{
+ int ret = 0;
+ if (active) {
+ ret += tc358743_write_reg(0x8544, 0x00, 1);
+ mdelay(500);
+ ret += tc358743_write_reg(0x8544, 0x10, 1);
+ } else {
+ ret += tc358743_write_reg(0x8544, 0x10, 1);
+ mdelay(500);
+ ret += tc358743_write_reg(0x8544, 0x00, 1);
+ }
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor_data *sensor = s->priv;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum tc358743_frame_rate frame_rate = tc358743_60_fps, frame_rate_now = tc358743_60_fps;
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+ det_work_enable(0);
+ /* Make sure power on */
+ tc_standby(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 60)
+ frame_rate = tc358743_60_fps;
+ else if (tgt_fps == 30)
+ frame_rate = tc358743_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ if ((u32)a->parm.capture.capturemode > tc358743_mode_MAX) {
+ a->parm.capture.capturemode = 0;
+ pr_debug("%s: Forse extended mode: %d \n", __func__,(u32)a->parm.capture.capturemode);
+ }
+
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 60)
+ frame_rate_now = tc358743_60_fps;
+ else if (tgt_fps == 30)
+ frame_rate_now = tc358743_30_fps;
+
+ if (frame_rate_now != frame_rate ||
+ sensor->streamcap.capturemode != (u32)a->parm.capture.capturemode ||
+ sensor->streamcap.extendedmode != (u32)a->parm.capture.extendedmode) {
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+ sensor->streamcap.extendedmode =
+ (u32)a->parm.capture.extendedmode;
+
+ pr_debug("%s: capture mode: %d extended mode: %d \n", __func__,sensor->streamcap.capturemode, sensor->streamcap.extendedmode);
+
+ ret = tc358743_init_mode(frame_rate,
+ sensor->streamcap.capturemode);
+ } else {
+ pr_debug("%s: Keep current settings\n", __func__);
+ }
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ det_work_enable(1);
+ return ret;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vc->value = tc358743_data.brightness;
+ break;
+ case V4L2_CID_HUE:
+ vc->value = tc358743_data.hue;
+ break;
+ case V4L2_CID_CONTRAST:
+ vc->value = tc358743_data.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ vc->value = tc358743_data.saturation;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ vc->value = tc358743_data.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ vc->value = tc358743_data.blue;
+ break;
+ case V4L2_CID_EXPOSURE:
+ vc->value = tc358743_data.ae_mode;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+
+ pr_debug("In tc358743:ioctl_s_ctrl %d\n",
+ vc->id);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ break;
+ case V4L2_CID_CONTRAST:
+ break;
+ case V4L2_CID_SATURATION:
+ break;
+ case V4L2_CID_HUE:
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_RED_BALANCE:
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ break;
+ case V4L2_CID_GAMMA:
+ break;
+ case V4L2_CID_EXPOSURE:
+ break;
+ case V4L2_CID_AUTOGAIN:
+ break;
+ case V4L2_CID_GAIN:
+ break;
+ case V4L2_CID_HFLIP:
+ break;
+ case V4L2_CID_VFLIP:
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+int get_pixelformat(int index)
+{
+ int ifmt;
+
+ for (ifmt = 0; ifmt < ARRAY_SIZE(tc358743_formats); ifmt++)
+ if (tc358743_mode_info_data[0][index].flags == tc358743_formats[ifmt].flags)
+ break;
+
+ if (ifmt == ARRAY_SIZE(tc358743_formats))
+ ifmt = 0; /* Default = RBG888 */
+ return ifmt;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ pr_debug("%s, INDEX: %d\n", __func__,fsize->index);
+ if (fsize->index > tc358743_mode_MAX)
+ return -EINVAL;
+
+ fsize->pixel_format = tc358743_formats[get_pixelformat(fsize->index)].pixelformat;
+ fsize->discrete.width =
+ tc358743_mode_info_data[0][fsize->index].width;
+ fsize->discrete.height =
+ tc358743_mode_info_data[0][fsize->index].height;
+ pr_debug("%s %d:%d format: %x\n", __func__, fsize->discrete.width, fsize->discrete.height, fsize->pixel_format);
+ return 0;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
+ "tc358743_mipi");
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+ pr_debug("%s\n", __func__);
+ return 0;
+}
+
+/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ pr_debug("%s\n", __func__);
+ if (fmt->index > tc358743_mode_MAX)
+ return -EINVAL;
+
+ fmt->pixelformat = tc358743_formats[get_pixelformat(fmt->index)].pixelformat;
+
+ pr_debug("%s: format: %x\n", __func__, fmt->pixelformat);
+ return 0;
+}
+
+static int ioctl_try_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_format *f)
+{
+ struct sensor_data *sensor = s->priv;
+ u32 tgt_fps; /* target frames per secound */
+ enum tc358743_frame_rate frame_rate;
+// enum image_size isize;
+ int ifmt;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ pr_debug("%s\n", __func__);
+
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 60) {
+ frame_rate = tc358743_60_fps;
+ } else if (tgt_fps == 30) {
+ frame_rate = tc358743_30_fps;
+ } else {
+ pr_debug("%s: %d fps (%d,%d) is not supported\n", __func__, tgt_fps, sensor->streamcap.timeperframe.denominator,sensor->streamcap.timeperframe.numerator);
+ return -EINVAL;
+ }
+
+ tc358743_data.pix.width = pix->width = tc358743_mode_info_data[frame_rate][sensor->streamcap.capturemode].width;
+ tc358743_data.pix.height = pix->height = tc358743_mode_info_data[frame_rate][sensor->streamcap.capturemode].height;
+
+ for (ifmt = 0; ifmt < ARRAY_SIZE(tc358743_formats); ifmt++)
+ if (tc358743_mode_info_data[frame_rate][sensor->streamcap.capturemode].flags == tc358743_formats[ifmt].flags)
+ break;
+
+ if (ifmt == ARRAY_SIZE(tc358743_formats))
+ ifmt = 0; /* Default = RBG888 */
+
+ tc358743_data.pix.pixelformat = pix->pixelformat = tc358743_formats[ifmt].pixelformat;
+ pix->field = V4L2_FIELD_NONE;
+ pix->bytesperline = pix->width * 4;
+ pix->sizeimage = pix->bytesperline * pix->height;
+ pix->priv = 0;
+
+ switch (pix->pixelformat) {
+ case V4L2_PIX_FMT_UYVY:
+ default:
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
+ break;
+ }
+
+ {
+ u32 u32val;
+ int ret = tc358743_read_reg(0x8520,&u32val);
+ pr_debug("SYS_STATUS: 0x%x, ret val: %d \n",u32val,ret);
+ ret = tc358743_read_reg(0x8521,&u32val);
+ pr_debug("VI_STATUS0: 0x%x, ret val: %d \n",u32val,ret);
+ ret = tc358743_read_reg(0x8522,&u32val);
+ pr_debug("VI_STATUS1: 0x%x, ret val: %d \n",u32val,ret);
+ ret = tc358743_read_reg(0x8525,&u32val);
+ pr_debug("VI_STATUS2: 0x%x, ret val: %d \n",u32val,ret);
+ ret = tc358743_read_reg(0x8528,&u32val);
+ pr_debug("VI_STATUS3: 0x%x, ret val: %d \n",u32val,ret);
+ pr_debug("%s %d:%d format: %x\n", __func__, pix->width, pix->height, pix->pixelformat);
+ }
+ return 0;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+
+ pr_debug("%s\n", __func__);
+ return ioctl_try_fmt_cap(s, f);
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ struct sensor_data *sensor = s->priv;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ int ret = 0;
+ enum tc358743_frame_rate frame_rate;
+ void *mipi_csi2_info;
+
+ pr_debug("%s\n", __func__);
+ tc358743_data.on = true;
+
+ /* mclk */
+ tgt_xclk = tc358743_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)TC358743_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)TC358743_XCLK_MIN);
+ tc358743_data.mclk = tgt_xclk;
+
+ pr_debug("%s: Setting mclk to %d MHz\n", __func__, tc358743_data.mclk / 1000000);
+// set_mclk_rate(&tc358743_data.mclk, tc358743_data.mclk_source);
+// pr_debug("%s: After mclk to %d MHz\n", __func__, tc358743_data.mclk / 1000000);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 60)
+ frame_rate = tc358743_60_fps;
+ else if (tgt_fps == 30)
+ frame_rate = tc358743_30_fps;
+ else
+ return -EINVAL;
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* enable mipi csi2 */
+ if (mipi_csi2_info) {
+ mipi_csi2_enable(mipi_csi2_info);
+ } else {
+ pr_err("Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+
+ pr_debug("%s done\n", __func__);
+ return ret;
+}
+
+/*!
+ * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Delinitialise the device when slave detaches to the master.
+ */
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+ void *mipi_csi2_info;
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* disable mipi csi2 */
+ if (mipi_csi2_info)
+ if (mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_disable(mipi_csi2_info);
+
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module and links them to the
+ * enumeration.
+ */
+static struct v4l2_int_ioctl_desc tc358743_ioctl_desc[] = {
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init},
+ {vidioc_int_dev_exit_num, ioctl_dev_exit},
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
+ {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
+ {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
+ {vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap},
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave tc358743_slave = {
+ .ioctls = tc358743_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(tc358743_ioctl_desc),
+};
+
+static struct v4l2_int_device tc358743_int_device = {
+ .module = THIS_MODULE,
+ .name = "tc358743",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &tc358743_slave,
+ },
+};
+
+
+#ifdef AUDIO_ENABLE
+struct imx_ssi {
+ struct platform_device *ac97_dev;
+
+ struct snd_soc_dai *imx_ac97;
+ struct clk *clk;
+ void __iomem *base;
+ int irq;
+ int fiq_enable;
+ unsigned int offset;
+
+ unsigned int flags;
+
+ void (*ac97_reset) (struct snd_ac97 *ac97);
+ void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+
+ struct imx_pcm_dma_params dma_params_rx;
+ struct imx_pcm_dma_params dma_params_tx;
+
+ int enabled;
+
+ struct platform_device *soc_platform_pdev;
+ struct platform_device *soc_platform_pdev_fiq;
+};
+#define SSI_SCR 0x10
+#define SSI_SRCR 0x20
+#define SSI_STCCR 0x24
+#define SSI_SRCCR 0x28
+#define SSI_SCR_I2S_MODE_NORM (0 << 5)
+#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
+#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
+#define SSI_I2S_MODE_MASK (3 << 5)
+#define SSI_SCR_SYN (1 << 4)
+#define SSI_SRCR_RSHFD (1 << 4)
+#define SSI_SRCR_RSCKP (1 << 3)
+#define SSI_SRCR_RFSI (1 << 2)
+#define SSI_SRCR_REFS (1 << 0)
+#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
+#define SSI_STCCR_WL_MASK (0xf << 13)
+#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
+#define SSI_SRCCR_WL_MASK (0xf << 13)
+/* Audio setup */
+
+static int imxpac_tc358743_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (ret) {
+ pr_err("%s: failed set cpu dai format\n", __func__);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (ret) {
+ pr_err("%s: failed set codec dai format\n", __func__);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+ CODEC_CLOCK, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ pr_err("%s: failed setting codec sysclk\n", __func__);
+ return ret;
+ }
+ snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
+ SND_SOC_CLOCK_IN);
+ if (ret) {
+ pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
+ return ret;
+ }
+#if 1
+// clear SSI_SRCR_RXBIT0 and SSI_SRCR_RSHFD in order to push Right-justified MSB data fro
+ {
+ struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 scr = 0, srcr = 0, stccr = 0, srccr = 0;
+
+ pr_debug("%s: base %p\n", __func__, (void *)ssi->base);
+ scr = readl(ssi->base + SSI_SCR);
+ pr_debug("%s: SSI_SCR before: %p\n", __func__, (void *)scr);
+ writel(scr, ssi->base + SSI_SCR);
+ pr_debug("%s: SSI_SCR after: %p\n", __func__, (void *)scr);
+
+ srcr = readl(ssi->base + SSI_SRCR);
+ pr_debug("%s: SSI_SRCR before: %p\n", __func__, (void *)srcr);
+ writel(srcr, ssi->base + SSI_SRCR);
+ pr_debug("%s: SSI_SRCR after: %p\n", __func__, (void *)srcr);
+
+ stccr = readl(ssi->base + SSI_STCCR);
+ pr_debug("%s: SSI_STCCR before: %p\n", __func__, (void *)stccr);
+ stccr &= ~SSI_STCCR_WL_MASK;
+ stccr |= SSI_STCCR_WL(16);
+ writel(stccr, ssi->base + SSI_STCCR);
+ pr_debug("%s: SSI_STCCR after: %p\n", __func__, (void *)stccr);
+
+ srccr = readl(ssi->base + SSI_SRCCR);
+ pr_debug("%s: SSI_SRCCR before: %p\n", __func__, (void *)srccr);
+ srccr &= ~SSI_SRCCR_WL_MASK;
+ srccr |= SSI_SRCCR_WL(16);
+ writel(srccr, ssi->base + SSI_SRCCR);
+ pr_debug("%s: SSI_SRCCR after: %p\n", __func__, (void *)srccr);
+ }
+#endif
+ return 0;
+}
+
+
+
+/* Headphones jack detection DAPM pins */
+static struct snd_soc_jack_pin hs_jack_pins_a[] = {
+};
+
+/* imx_3stack card dapm widgets */
+static struct snd_soc_dapm_widget imx_3stack_dapm_widgets_a[] = {
+};
+
+
+
+static struct snd_kcontrol_new tc358743_machine_controls_a[] = {
+};
+
+/* imx_3stack machine connections to the codec pins */
+static struct snd_soc_dapm_route audio_map_a[] = {
+};
+
+static int imx_3stack_tc358743_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret;
+ struct snd_soc_jack *hs_jack;
+
+ struct snd_soc_jack_pin *hs_jack_pins;
+ int hs_jack_pins_size;
+ struct snd_soc_dapm_widget *imx_3stack_dapm_widgets;
+ int imx_3stack_dapm_widgets_size;
+ struct snd_kcontrol_new *tc358743_machine_controls;
+ int tc358743_machine_controls_size;
+ struct snd_soc_dapm_route *audio_map;
+ int audio_map_size;
+ int gpio_num = -1;
+ char *gpio_name;
+
+ pr_debug("%s started\n", __func__);
+
+ hs_jack_pins = hs_jack_pins_a;
+ hs_jack_pins_size = ARRAY_SIZE(hs_jack_pins_a);
+ imx_3stack_dapm_widgets = imx_3stack_dapm_widgets_a;
+ imx_3stack_dapm_widgets_size = ARRAY_SIZE(imx_3stack_dapm_widgets_a);
+ tc358743_machine_controls = tc358743_machine_controls_a;
+ tc358743_machine_controls_size = ARRAY_SIZE(tc358743_machine_controls_a);
+ audio_map = audio_map_a;
+ audio_map_size = ARRAY_SIZE(audio_map_a);
+ gpio_num = -1; //card_a_gpio_num;
+ gpio_name = NULL;
+
+ ret = snd_soc_add_controls(codec, tc358743_machine_controls,
+ tc358743_machine_controls_size);
+ if (ret) {
+ pr_err("%s: snd_soc_add_controls failed. err = %d\n", __func__, ret);
+ return ret;
+ }
+ /* Add imx_3stack specific widgets */
+ snd_soc_dapm_new_controls(&codec->dapm, imx_3stack_dapm_widgets,
+ imx_3stack_dapm_widgets_size);
+
+ /* Set up imx_3stack specific audio path audio_map */
+ snd_soc_dapm_add_routes(&codec->dapm, audio_map, audio_map_size);
+
+ snd_soc_dapm_enable_pin(&codec->dapm, hs_jack_pins->pin);
+ snd_soc_dapm_sync(&codec->dapm);
+
+ hs_jack = kzalloc(sizeof(struct snd_soc_jack), GFP_KERNEL);
+
+
+ ret = snd_soc_jack_new(codec, hs_jack_pins->pin,
+ SND_JACK_HEADPHONE, hs_jack);
+ if (ret) {
+ pr_err("%s: snd_soc_jack_new failed. err = %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = snd_soc_jack_add_pins(hs_jack,hs_jack_pins_size,
+ hs_jack_pins);
+ if (ret) {
+ pr_err("%s: snd_soc_jack_add_pinsfailed. err = %d\n", __func__, ret);
+ return ret;
+ }
+ return 0;
+}
+
+
+static struct snd_soc_ops imxpac_tc358743_snd_ops = {
+ .hw_params = imxpac_tc358743_hw_params,
+};
+
+static struct snd_soc_dai_link imxpac_tc358743_dai = {
+ .name = "tc358743",
+ .stream_name = "TC358743",
+ .codec_dai_name = "tc358743-hifi",
+ .platform_name = "imx-pcm-audio.2",
+ .codec_name = "tc358743_mipi.1-000f",
+ .cpu_dai_name = "imx-ssi.2",
+ .init = imx_3stack_tc358743_init,
+ .ops = &imxpac_tc358743_snd_ops,
+};
+
+static struct snd_soc_card imxpac_tc358743 = {
+ .name = "cpuimx-audio_hdmi_in",
+ .dai_link = &imxpac_tc358743_dai,
+ .num_links = 1,
+};
+
+static struct platform_device *imxpac_tc358743_snd_device;
+static struct platform_device *imxpac_tc358743_snd_device;
+
+static int imx_audmux_config(int slave, int master)
+{
+ unsigned int ptcr, pdcr;
+ slave = slave - 1;
+ master = master - 1;
+
+ /* SSI0 mastered by port 5 */
+ ptcr = MXC_AUDMUX_V2_PTCR_SYN |
+ MXC_AUDMUX_V2_PTCR_TFSDIR |
+ MXC_AUDMUX_V2_PTCR_TFSEL(master | 0x8) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR |
+ MXC_AUDMUX_V2_PTCR_RFSDIR |
+ MXC_AUDMUX_V2_PTCR_RFSEL(master | 0x8) |
+ MXC_AUDMUX_V2_PTCR_RCLKDIR |
+ MXC_AUDMUX_V2_PTCR_RCSEL(master | 0x8) |
+ MXC_AUDMUX_V2_PTCR_TCSEL(master | 0x8);
+ pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master);
+ mxc_audmux_v2_configure_port(slave, ptcr, pdcr);
+
+ ptcr = MXC_AUDMUX_V2_PTCR_SYN;
+ pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master);
+ mxc_audmux_v2_configure_port(master, ptcr, pdcr);
+ return 0;
+}
+
+static int __devinit imx_tc358743_probe(struct platform_device *pdev)
+{
+ struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
+ int ret = 0;
+
+
+ imx_audmux_config(plat->src_port, plat->ext_port);
+
+ ret = -EINVAL;
+ if (plat->init && plat->init())
+ return ret;
+
+ printk("%s %d %s\n",__func__,__LINE__,pdev->name);
+ return 0;
+}
+
+static int imx_tc358743_remove(struct platform_device *pdev)
+{
+ struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
+
+ if (plat->finit)
+ plat->finit();
+
+ return 0;
+}
+
+static struct platform_driver imx_tc358743_audio1_driver = {
+ .probe = imx_tc358743_probe,
+ .remove = imx_tc358743_remove,
+ .driver = {
+ .name = "imx-tc358743",
+ },
+};
+
+
+/* Codec setup */
+static int tc358743_codec_probe(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+static int tc358743_codec_remove(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+static int tc358743_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+// tc358743_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int tc358743_codec_resume(struct snd_soc_codec *codec)
+{
+// tc358743_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+
+static int tc358743_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ return 0;
+}
+
+static const u8 tc358743_reg[0] = {
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_tc358743 = {
+ .set_bias_level = tc358743_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(tc358743_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = tc358743_reg,
+ .probe = tc358743_codec_probe,
+ .remove = tc358743_codec_remove,
+ .suspend = tc358743_codec_suspend,
+ .resume = tc358743_codec_resume,
+};
+
+#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
+#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static int tc358743_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ return 0;
+}
+
+static int tc358743_mute(struct snd_soc_dai *dai, int mute)
+{
+ return 0;
+}
+
+static int tc358743_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int tc358743_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ return 0;
+}
+
+static struct snd_soc_dai_ops tc358743_dai_ops = {
+ .hw_params = tc358743_hw_params,
+ .digital_mute = tc358743_mute,
+ .set_sysclk = tc358743_set_dai_sysclk,
+ .set_fmt = tc358743_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver tc358743_dai = {
+ .name = "tc358743-hifi",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AIC3X_RATES,
+ .formats = AIC3X_FORMATS,},
+ .ops = &tc358743_dai_ops,
+ .symmetric_rates = 1,
+};
+
+#endif
+
+static char tc358743_mode_list[16][12] =
+{
+ "None",
+ "VGA",
+ "240p/480i",
+ "288p/576i",
+ "W240p/480i",
+ "W288p/576i",
+ "480p",
+ "576p",
+ "W480p",
+ "W576p",
+ "WW480p",
+ "WW576p",
+ "720p",
+ "1035i",
+ "1080i",
+ "1080p"
+};
+
+static char tc358743_fps_list[tc358743_max_fps+1] =
+{
+[tc358743_60_fps] = 60,
+[tc358743_30_fps] = 30,
+[tc358743_max_fps] = 0
+};
+
+static int tc358743_audio_list[16] =
+{
+ 44100,
+ 0,
+ 48000,
+ 32000,
+ 22050,
+ 384000,
+ 24000,
+ 352800,
+ 88200,
+ 768000,
+ 96000,
+ 705600,
+ 176400,
+ 0,
+ 192000,
+ 0
+};
+
+static char str_on[80];
+static void report_netlink(void)
+{
+ char *envp[2];
+ envp[0] = &str_on[0];
+ envp[1] = NULL;
+ sprintf(envp[0], "HDMI RX: %d (%s) %d %d", (unsigned char)hdmi_mode & 0xf, tc358743_mode_list[(unsigned char)hdmi_mode & 0xf], tc358743_fps_list[fps], tc358743_audio_list[audio]);
+ kobject_uevent_env(&(tc358743_data.i2c_client->dev.kobj), KOBJ_CHANGE, envp);
+ det_work_timeout = DET_WORK_TIMEOUT_DEFAULT;
+ pr_debug("%s: HDMI RX (%d) mode: %s fps: %d (%d, %d) audio: %d\n", __func__, (unsigned char)hdmi_mode, tc358743_mode_list[(unsigned char)hdmi_mode & 0xf], fps, bounce, det_work_timeout, tc358743_audio_list[audio]);
+}
+
+static void det_worker(struct work_struct *work)
+{
+ u32 u32val;
+ u16 reg;
+ int ret;
+
+ mutex_lock(&access_lock);
+ if (!det_work_disable) {
+ reg = 0x8621;
+ ret = tc358743_read_reg(reg, &u32val);
+ if (ret > 0) {
+ if (audio != (((unsigned char)u32val) & 0x0f)) {
+ audio = ((unsigned char)u32val) & 0x0f;
+ report_netlink();
+ }
+ }
+ reg = 0x852f;
+ ret = tc358743_read_reg(reg, &u32val);
+ if (ret > 0) {
+ while (1) {
+ if (u32val & TC3587430_HDMI_DETECT) {
+ lock = u32val & TC3587430_HDMI_DETECT;
+ reg = 0x8521;
+ ret = tc358743_read_reg(reg, &u32val);
+ if (ret < 0) {
+ pr_err("%s: Error reading mode\n", __func__);
+ }
+ } else {
+ if (lock) { // check if it is realy un-plug
+ lock = 0;
+ u32val = 0x0;
+ hdmi_mode = 0xF0; // fake mode to detect un-plug if mode was not detected before.
+ }
+ }
+ if ((unsigned char)hdmi_mode != (unsigned char)u32val) {
+ if (u32val)
+ det_work_timeout = DET_WORK_TIMEOUT_DEFERRED;
+ else
+ det_work_timeout = DET_WORK_TIMEOUT_DEFAULT;
+ bounce = MAX_BOUNCE;
+ pr_debug("%s: HDMI RX (%d != %d) mode: %s fps: %d (%d, %d)\n", __func__, (unsigned char)hdmi_mode, (unsigned char)u32val, tc358743_mode_list[(unsigned char)hdmi_mode & 0xf], fps, bounce, det_work_timeout);
+ hdmi_mode = u32val;
+ } else if (bounce) {
+ bounce--;
+ det_work_timeout = DET_WORK_TIMEOUT_DEFAULT;
+ }
+
+ if (1 == bounce) {
+ if (hdmi_mode >= 0xe) {
+ reg = 0x852f;
+ ret = tc358743_read_reg(reg, &u32val);
+ if (ret > 0)
+ fps = ((((unsigned char)u32val) & 0x0f) > 0xa)? tc358743_60_fps: tc358743_30_fps;
+ }
+ reg = 0x8621;
+ ret = tc358743_read_reg(reg, &u32val);
+ if (ret > 0) {
+ audio = ((unsigned char)u32val) & 0x0f;
+ report_netlink();
+ }
+ }
+ break;
+ }
+ } else {
+ pr_err("%s: Error reading lock\n", __func__);
+ }
+ } else {
+ det_work_timeout = DET_WORK_TIMEOUT_DEFERRED;
+ }
+ mutex_unlock(&access_lock);
+ schedule_delayed_work(&(det_work), msecs_to_jiffies(det_work_timeout));
+}
+
+static irqreturn_t tc358743_detect_handler(int irq, void *data)
+{
+
+ pr_debug("%s: IRQ %d\n", __func__, tc358743_data.i2c_client->irq);
+ schedule_delayed_work(&(det_work), msecs_to_jiffies(det_work_timeout));
+ return IRQ_HANDLED;
+}
+
+
+/*!
+ * tc358743 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+#define DUMP_LENGTH 256
+static u16 regoffs = 0;
+
+static ssize_t tc358743_show_regdump(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i, len = 0;
+ int retval;
+ u32 u32val;
+
+ mutex_lock(&access_lock);
+ for (i=0; i<DUMP_LENGTH; ) {
+ retval = tc358743_read_reg(regoffs+i, &u32val);
+ if (retval < 0) {
+ u32val =0xff;
+ retval = 1;
+ }
+ while (retval-- > 0) {
+ if (0 == (i & 0xf))
+ len += sprintf(buf+len, "\n%04X:", regoffs+i);
+ len += sprintf(buf+len, " %02X", u32val&0xff);
+ u32val >>= 8;
+ i++;
+ }
+ }
+ mutex_unlock(&access_lock);
+ len += sprintf(buf+len, "\n");
+ return len;
+}
+
+static DEVICE_ATTR(regdump, S_IRUGO, tc358743_show_regdump, NULL);
+
+static ssize_t tc358743_store_regoffs(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 val;
+ int retval;
+ retval = sscanf(buf, "%x", &val);
+ if (1 == retval)
+ regoffs = (u16)val;
+ return count;
+}
+
+static ssize_t tc358743_show_regoffs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len += sprintf(buf+len, "0x%04X\n", regoffs);
+ return len;
+}
+
+static DEVICE_ATTR(regoffs, S_IRUGO|S_IWUSR, tc358743_show_regoffs, tc358743_store_regoffs);
+
+static ssize_t tc358743_store_hpd(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 val;
+ int retval;
+ retval = sscanf(buf, "%d", &val);
+ if (1 == retval)
+ hpd_active = (u16)val;
+ return count;
+}
+
+static ssize_t tc358743_show_hpd(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len += sprintf(buf+len, "%d\n", hpd_active);
+ return len;
+}
+
+static DEVICE_ATTR(hpd, S_IRUGO|S_IWUSR, tc358743_show_hpd, tc358743_store_hpd);
+
+static ssize_t tc358743_show_hdmirx(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len += sprintf(buf+len, "%d\n", hdmi_mode);
+ return len;
+}
+
+static DEVICE_ATTR(hdmirx, S_IRUGO, tc358743_show_hdmirx, NULL);
+
+static ssize_t tc358743_show_fps(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len += sprintf(buf+len, "%d\n", tc358743_fps_list[fps]);
+ return len;
+}
+
+static DEVICE_ATTR(fps, S_IRUGO, tc358743_show_fps, NULL);
+
+#ifdef AUDIO_ENABLE
+static ssize_t tc358743_show_audio(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len += sprintf(buf+len, "%d\n", tc358743_audio_list[audio]);
+ return len;
+}
+
+static DEVICE_ATTR(audio, S_IRUGO, tc358743_show_audio, NULL);
+#endif
+
+static int tc358743_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pwm_device *pwm;
+ struct device *dev = &client->dev;
+ int retval;
+ struct regmap *gpr;
+ struct sensor_data *sensor = &tc358743_data;
+ u32 u32val;
+
+
+ /* request power down pin */
+ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+ if (!gpio_is_valid(pwn_gpio)) {
+ dev_warn(dev, "no sensor pwdn pin available");
+ } else {
+ retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
+ "tc_mipi_pwdn");
+ if (retval < 0) {
+ dev_warn(dev, "request of pwn_gpio failed");
+ return retval;
+ }
+ }
+ /* request reset pin */
+ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+ if (!gpio_is_valid(rst_gpio)) {
+ dev_warn(dev, "no sensor reset pin available");
+ return -EINVAL;
+ }
+ retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
+ "tc_mipi_reset");
+ if (retval < 0) {
+ dev_warn(dev, "request of tc_mipi_reset failed");
+ return retval;
+ }
+
+ /* Set initial values for the sensor struct. */
+ memset(sensor, 0, sizeof(*sensor));
+
+ sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
+ if (IS_ERR(sensor->sensor_clk)) {
+ /* assuming clock enabled by default */
+ sensor->sensor_clk = NULL;
+ dev_err(dev, "clock-frequency missing or invalid\n");
+ return PTR_ERR(sensor->sensor_clk);
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk",
+ &(sensor->mclk));
+ if (retval) {
+ dev_err(dev, "mclk missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "mclk_source",
+ (u32 *) &(sensor->mclk_source));
+ if (retval) {
+ dev_err(dev, "mclk_source missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "ipu_id",
+ &sensor->ipu_id);
+ if (retval) {
+ dev_err(dev, "ipu_id missing or invalid\n");
+ return retval;
+ }
+
+ retval = of_property_read_u32(dev->of_node, "csi_id",
+ &(sensor->csi));
+ if (retval) {
+ dev_err(dev, "csi id missing or invalid\n");
+ return retval;
+ }
+ if (((unsigned)sensor->ipu_id > 1) || ((unsigned)sensor->csi > 1)) {
+ dev_err(dev, "invalid ipu/csi\n");
+ return -EINVAL;
+ }
+
+ clk_prepare_enable(sensor->sensor_clk);
+
+ sensor->io_init = tc_reset;
+ sensor->i2c_client = client;
+ sensor->pix.pixelformat = tc358743_formats[0].pixelformat;
+ sensor->streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ sensor->streamcap.capturemode = 0;
+ sensor->streamcap.extendedmode = tc358743_mode_1080P_1920_1080;
+ sensor->streamcap.timeperframe.denominator = DEFAULT_FPS;
+ sensor->streamcap.timeperframe.numerator = 1;
+
+ sensor->pix.width = tc358743_mode_info_data[0][sensor->streamcap.capturemode].width;
+ sensor->pix.height = tc358743_mode_info_data[0][sensor->streamcap.capturemode].height;
+ pr_debug("%s: format: %x, capture mode: %d extended mode: %d fps: %d width: %d height: %d\n",__func__,
+ sensor->pix.pixelformat,
+ sensor->streamcap.capturemode, sensor->streamcap.extendedmode,
+ sensor->streamcap.timeperframe.denominator *
+ sensor->streamcap.timeperframe.numerator,
+ sensor->pix.width,
+ sensor->pix.height);
+
+ pwm = pwm_get(dev, NULL);
+ if (!IS_ERR(pwm)) {
+ dev_info(dev, "found pwm%d, period=%d\n", pwm->pwm, pwm->period);
+ pwm_config(pwm, pwm->period >> 1, pwm->period);
+ pwm_enable(pwm);
+ }
+
+ tc_power_on(dev);
+ tc_reset();
+ tc_standby(0);
+
+ retval = tc358743_read_reg(TC358743_CHIP_ID_HIGH_BYTE, &u32val);
+ if (retval < 0) {
+ pr_err("%s:cannot find camera\n", __func__);
+ retval = -ENODEV;
+ goto err4;
+ }
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ if (of_machine_is_compatible("fsl,imx6q")) {
+ if (sensor->csi == sensor->ipu_id) {
+ int mask = sensor->csi ? (1 << 20) : (1 << 19);
+
+ regmap_update_bits(gpr, IOMUXC_GPR1, mask, 0);
+ }
+ } else if (of_machine_is_compatible("fsl,imx6dl")) {
+ int mask = sensor->csi ? (7 << 3) : (7 << 0);
+ int val = sensor->csi ? (3 << 3) : (0 << 0);
+
+ if (sensor->ipu_id) {
+ dev_err(dev, "invalid ipu\n");
+ return -EINVAL;
+ }
+ regmap_update_bits(gpr, IOMUXC_GPR13, mask, val);
+ }
+ } else {
+ pr_err("%s: failed to find fsl,imx6q-iomux-gpr regmap\n",
+ __func__);
+ }
+
+ tc358743_int_device.priv = sensor;
+
+ //retval = device_create_file(&client->dev, &dev_attr_audio);
+ retval = device_create_file(&client->dev, &dev_attr_fps);
+ retval = device_create_file(&client->dev, &dev_attr_hdmirx);
+ retval = device_create_file(&client->dev, &dev_attr_hpd);
+ retval = device_create_file(&client->dev, &dev_attr_regoffs);
+ retval = device_create_file(&client->dev, &dev_attr_regdump);
+
+ if (retval) {
+ pr_err("%s: create bin file failed, error=%d\n",
+ __func__, retval);
+ goto err4;
+ }
+
+#ifdef AUDIO_ENABLE
+/* Audio setup */
+ retval = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_tc358743, &tc358743_dai, 1);
+ if (retval) {
+ pr_err("%s: register failed, error=%d\n",
+ __func__, retval);
+ goto err4;
+ }
+
+ retval = platform_driver_register(&imx_tc358743_audio1_driver);
+ if (retval) {
+ pr_err("%s: Platform driver register failed, error=%d\n",
+ __func__, retval);
+ goto err4;
+ }
+
+ imxpac_tc358743_snd_device = platform_device_alloc("soc-audio", 5);
+ if (!imxpac_tc358743_snd_device) {
+ pr_err("%s: Platform device allocation failed, error=%d\n",
+ __func__, retval);
+ goto err4;
+ }
+
+ platform_set_drvdata(imxpac_tc358743_snd_device, &imxpac_tc358743);
+ retval = platform_device_add(imxpac_tc358743_snd_device);
+
+ if (retval) {
+ pr_err("%s: Platform device add failed, error=%d\n",
+ __func__, retval);
+ platform_device_put(imxpac_tc358743_snd_device);
+ goto err4;
+ }
+#endif
+
+#if 1
+ INIT_DELAYED_WORK(&(det_work), det_worker);
+ if (sensor->i2c_client->irq) {
+ retval = request_irq(sensor->i2c_client->irq, tc358743_detect_handler,
+ IRQF_SHARED | IRQF_TRIGGER_FALLING,
+ "tc358743_det", sensor);
+ if (retval < 0)
+ dev_warn(&sensor->i2c_client->dev,
+ "cound not request det irq %d\n",
+ sensor->i2c_client->irq);
+ }
+
+ schedule_delayed_work(&(det_work), msecs_to_jiffies(det_work_timeout));
+#endif
+ retval = tc358743_reset(sensor);
+
+ tc_standby(1);
+ retval = v4l2_int_device_register(&tc358743_int_device);
+ if (retval) {
+ pr_err("%s: v4l2_int_device_register failed, error=%d\n",
+ __func__, retval);
+ goto err4;
+ }
+ pr_debug("%s: finished, error=%d\n",
+ __func__, retval);
+ return retval;
+
+err4:
+ pr_err("%s: failed, error=%d\n",
+ __func__, retval);
+ return retval;
+}
+
+/*!
+ * tc358743 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int tc358743_remove(struct i2c_client *client)
+{
+ // Stop delayed work
+ cancel_delayed_work_sync(&(det_work));
+
+ // Remove IRQ
+ if (tc358743_data.i2c_client->irq) {
+ free_irq(tc358743_data.i2c_client->irq, &tc358743_data);
+ }
+
+ /*Remove sysfs entries*/
+ device_remove_file(&client->dev, &dev_attr_fps);
+ device_remove_file(&client->dev, &dev_attr_hdmirx);
+ device_remove_file(&client->dev, &dev_attr_hpd);
+ device_remove_file(&client->dev, &dev_attr_regoffs);
+ device_remove_file(&client->dev, &dev_attr_regdump);
+
+ v4l2_int_device_unregister(&tc358743_int_device);
+
+ if (gpo_regulator) {
+ regulator_disable(gpo_regulator);
+ regulator_put(gpo_regulator);
+ }
+
+ if (analog_regulator) {
+ regulator_disable(analog_regulator);
+ regulator_put(analog_regulator);
+ }
+
+ if (core_regulator) {
+ regulator_disable(core_regulator);
+ regulator_put(core_regulator);
+ }
+
+ if (io_regulator) {
+ regulator_disable(io_regulator);
+ regulator_put(io_regulator);
+ }
+
+ return 0;
+}
+
+/*!
+ * tc358743 init function
+ * Called by insmod tc358743_camera.ko.
+ *
+ * @return Error code indicating success or failure
+ */
+static __init int tc358743_init(void)
+{
+ int err;
+
+ err = i2c_add_driver(&tc358743_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * tc358743 cleanup function
+ * Called on rmmod tc358743_camera.ko
+ *
+ * @return Error code indicating success or failure
+ */
+static void __exit tc358743_clean(void)
+{
+ i2c_del_driver(&tc358743_i2c_driver);
+}
+
+module_init(tc358743_init);
+module_exit(tc358743_clean);
+
+MODULE_AUTHOR("Panasonic Avionics Corp.");
+MODULE_DESCRIPTION("Toshiba TC358743 HDMI-to-CSI2 Bridge MIPI Input Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/platform/mxc/output/mxc_vout.c b/drivers/media/platform/mxc/output/mxc_vout.c
index 7d2dcdd81888..114ab973d890 100644
--- a/drivers/media/platform/mxc/output/mxc_vout.c
+++ b/drivers/media/platform/mxc/output/mxc_vout.c
@@ -381,8 +381,7 @@ static int update_setting_from_fbi(struct mxc_vout_output *vout,
if (!strcmp(fbi->fix.id, g_fb_setting[i].name)) {
vout->crop_bounds = g_fb_setting[i].crop_bounds;
vout->disp_fmt = g_fb_setting[i].disp_fmt;
- vout->disp_support_csc =
- g_fb_setting[i].disp_support_csc;
+ vout->disp_support_csc = false;
vout->disp_support_windows =
g_fb_setting[i].disp_support_windows;
found = true;
diff --git a/drivers/mfd/pca9450.c b/drivers/mfd/pca9450.c
index 1586852ce52d..9322c30f3eea 100644
--- a/drivers/mfd/pca9450.c
+++ b/drivers/mfd/pca9450.c
@@ -177,6 +177,10 @@ static struct pca9450_board *pca9450_parse_dt(struct i2c_client *client,
else
board_info->irq_base = -1;
+ r = of_property_read_u32(np, "i2c-lt-en", &prop);
+ if (!r)
+ board_info->i2c_lt_en = 0x100 | prop;
+
return board_info;
err_intr:
@@ -237,6 +241,17 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
}
dev_info(pca9450->dev, "Device ID=0x%X\n", ret);
+ if ((pmic_plat_data->i2c_lt_en > 0xff) &&
+ (pmic_plat_data->i2c_lt_en < 0x104)) {
+ ret = pca9450_reg_write(pca9450, PCA9450_CONFIG2,
+ pmic_plat_data->i2c_lt_en & 0xff);
+ if (ret < 0) {
+ dev_err(pca9450->dev, "%s(): Read PCA9450_REG_DEVICE failed!\n",
+ __func__);
+ goto err;
+ }
+ }
+
pca9450_irq_init(pca9450, of_pmic_plat_data);
ret = mfd_add_devices(pca9450->dev, -1,
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 508349399f8a..a21ecbdb8011 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -1357,7 +1357,7 @@ static void stmpe_of_probe(struct stmpe_platform_data *pdata,
pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
- for_each_child_of_node(np, child) {
+ for_each_available_child_of_node(np, child) {
if (of_node_name_eq(child, "stmpe_gpio")) {
pdata->blocks |= STMPE_BLOCK_GPIO;
} else if (of_node_name_eq(child, "stmpe_keypad")) {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 231b224cbec1..2bb61a41e439 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -243,7 +243,6 @@ static struct esdhc_soc_data usdhc_imx8qxp_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
- | ESDHC_FLAG_CQHCI
| ESDHC_FLAG_STATE_LOST_IN_LPMODE
| ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME,
};
@@ -252,7 +251,7 @@ static struct esdhc_soc_data usdhc_imx8mm_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
- | ESDHC_FLAG_CQHCI | ESDHC_FLAG_BUSFREQ
+ | ESDHC_FLAG_BUSFREQ
| ESDHC_FLAG_STATE_LOST_IN_LPMODE,
};
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d0daa28407ed..6d43d11de25c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2822,8 +2822,9 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
if (host->data || host->data_cmd ||
(host->cmd && sdhci_data_line_cmd(host->cmd))) {
- pr_err("%s: Timeout waiting for hardware interrupt.\n",
- mmc_hostname(host->mmc));
+ pr_err("%s: Timeout waiting for hardware interrupt. retries left=%d opcode=%x\n",
+ mmc_hostname(host->mmc), host->cmd ? host->cmd->retries : 0,
+ host->cmd ? host->cmd->opcode : 0);
sdhci_dumpregs(host);
if (host->data) {
diff --git a/drivers/mxc/hantro_845_h1/Kconfig b/drivers/mxc/hantro_845_h1/Kconfig
index 72936da4ef4a..1b2f81856c75 100755
--- a/drivers/mxc/hantro_845_h1/Kconfig
+++ b/drivers/mxc/hantro_845_h1/Kconfig
@@ -8,6 +8,7 @@ menu "MXC HANTRO(Video Processing Unit) encoder support"
config MXC_HANTRO_845_H1
tristate "Support for MXC HANTRO(Video Processing Unit) encoder"
default y
+ select COMPAT
---help---
VPU codec device.
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index c5b82f78421f..eb9cc785a4a3 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -3102,14 +3102,16 @@ void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id)
_ipu_get(ipu);
+ if (ipu->irq_list[irq].dev_id != dev_id)
+ return;
+
spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
/* disable the interrupt */
reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
reg &= ~IPUIRQ_2_MASK(irq);
ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
- if (ipu->irq_list[irq].dev_id == dev_id)
- memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
+ memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
diff --git a/drivers/mxc/mipi/mxc_mipi_csi2.c b/drivers/mxc/mipi/mxc_mipi_csi2.c
index 62b77a117a68..860080ada273 100644
--- a/drivers/mxc/mipi/mxc_mipi_csi2.c
+++ b/drivers/mxc/mipi/mxc_mipi_csi2.c
@@ -461,7 +461,7 @@ static int mipi_csi2_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gmipi_csi2);
- dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
+ dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed ipu%d csi%d\n", gmipi_csi2->ipu_id, gmipi_csi2->csi_id);
dev_info(&pdev->dev, "i.MX MIPI CSI2 dphy version is 0x%x\n",
mipi_csi2_dphy_ver);
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 8a1c7cc7b206..e44173999fc0 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -2167,7 +2167,12 @@ static int __maybe_unused flexcan_suspend(struct device *device)
if (err)
return err;
} else {
- flexcan_chip_stop(dev);
+ err = flexcan_chip_disable(priv);
+ if (err) {
+ netif_device_attach(dev);
+ netif_start_queue(dev);
+ return err;
+ }
err = pm_runtime_force_suspend(device);
if (err)
@@ -2220,6 +2225,7 @@ static int __maybe_unused flexcan_runtime_suspend(struct device *device)
struct flexcan_priv *priv = netdev_priv(dev);
flexcan_clks_disable(priv);
+ pinctrl_pm_select_sleep_state(priv->dev);
return 0;
}
@@ -2229,6 +2235,7 @@ static int __maybe_unused flexcan_runtime_resume(struct device *device)
struct net_device *dev = dev_get_drvdata(device);
struct flexcan_priv *priv = netdev_priv(dev);
+ pinctrl_pm_select_default_state(priv->dev);
return flexcan_clks_enable(priv);
}
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
index 1c50788055cb..d4b68eb5d386 100644
--- a/drivers/net/can/spi/Kconfig
+++ b/drivers/net/can/spi/Kconfig
@@ -15,4 +15,6 @@ config CAN_MCP251X
Driver for the Microchip MCP251x and MCP25625 SPI CAN
controllers.
+source "drivers/net/can/spi/mcp25xxfd/Kconfig"
+
endmenu
diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile
index f115b2c46623..769197785331 100644
--- a/drivers/net/can/spi/Makefile
+++ b/drivers/net/can/spi/Makefile
@@ -6,3 +6,5 @@
obj-$(CONFIG_CAN_HI311X) += hi311x.o
obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
+
+obj-y += mcp25xxfd/
diff --git a/drivers/net/can/spi/mcp25xxfd/Kconfig b/drivers/net/can/spi/mcp25xxfd/Kconfig
new file mode 100644
index 000000000000..1d2bd95febfe
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig CAN_MCP25XXFD
+ tristate "Microchip MCP25xxFD SPI CAN controllers"
+ depends on HAS_DMA
+ help
+ Driver for the Microchip MCP25XXFD SPI FD-CAN controller family.
+
+if CAN_MCP25XXFD
+
+config CAN_MCP25XXFD_DEBUG_FS
+ bool "Enable debugfs for MCP25xxFD SPI driver"
+ depends on DEBUG_FS
+ help
+ Choose Y to enable RX/TX and FIFO statistics.
+
+endif
diff --git a/drivers/net/can/spi/mcp25xxfd/Makefile b/drivers/net/can/spi/mcp25xxfd/Makefile
new file mode 100644
index 000000000000..5b3c6819d716
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/Makefile
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CAN_MCP25XXFD) += mcp25xxfd.o
+
+mcp25xxfd-objs := mcp25xxfd_base.o
+mcp25xxfd-objs += mcp25xxfd_can.o
+mcp25xxfd-objs += mcp25xxfd_can_fifo.o
+mcp25xxfd-objs += mcp25xxfd_can_int.o
+mcp25xxfd-objs += mcp25xxfd_can_rx.o
+mcp25xxfd-objs += mcp25xxfd_can_tx.o
+mcp25xxfd-objs += mcp25xxfd_clock.o
+mcp25xxfd-objs += mcp25xxfd_cmd.o
+mcp25xxfd-objs += mcp25xxfd_crc.o
+mcp25xxfd-objs += mcp25xxfd_ecc.o
+mcp25xxfd-objs += mcp25xxfd_int.o
+
+mcp25xxfd-$(CONFIG_CAN_MCP25XXFD_DEBUG_FS) += mcp25xxfd_can_debugfs.o
+mcp25xxfd-$(CONFIG_CAN_MCP25XXFD_DEBUG_FS) += mcp25xxfd_debugfs.o
+mcp25xxfd-$(CONFIG_GPIOLIB) += mcp25xxfd_gpio.o
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.c
new file mode 100644
index 000000000000..d9396e8819e8
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "mcp25xxfd_base.h"
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_clock.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_debugfs.h"
+#include "mcp25xxfd_ecc.h"
+#include "mcp25xxfd_gpio.h"
+#include "mcp25xxfd_int.h"
+#include "mcp25xxfd_priv.h"
+
+/* Device description and rational:
+ *
+ * The mcp25xxfd is a CanFD controller that also supports can2.0 only
+ * modes.
+ * It is connected via spi to the host and requires at minimum a single
+ * irq line in addition to the SPI lines - it is not mentioned explicitly
+ * in the documentation but in principle SPI 3-wire should be possible.
+ *
+ * The clock connected is typically 4MHz, 20MHz or 40MHz.
+ * When using a 4MHz clock the controller can use an integrated PLL to
+ * get 40MHz.
+ *
+ * The controller itself has 2KB of SRAM for CAN-data.
+ * ECC can get enabled for SRAM.
+ * CRC-16 checksumming of SPI transfers can get implemented
+ * - some optimization options may not be efficient in such a situation.
+ * - more SPI bus bandwidth is used for transfer of CRCs and
+ * transfer length information
+ *
+ * It also contains 2 GPIO pins that can get used either as interrupt lines
+ * or GPIO IN or Out or STANDBY flags.
+ * In addition there is a PIN that allows output of a (divided) clock out
+ * or as a SOF (Start of Can FRAME) interrupt line - e.g for wakeup.
+ */
+
+int mcp25xxfd_base_power_enable(struct regulator *reg, int enable)
+{
+ if (IS_ERR_OR_NULL(reg))
+ return 0;
+
+ if (enable)
+ return regulator_enable(reg);
+ else
+ return regulator_disable(reg);
+}
+
+static const struct of_device_id mcp25xxfd_of_match[] = {
+ {
+ .compatible = "microchip,mcp2517fd",
+ .data = (void *)CAN_MCP2517FD,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mcp25xxfd_of_match);
+
+static int mcp25xxfd_base_probe(struct spi_device *spi)
+{
+ const struct of_device_id *of_id =
+ of_match_device(mcp25xxfd_of_match, &spi->dev);
+ struct mcp25xxfd_priv *priv;
+ int ret;
+
+ /* as irq_create_fwspec_mapping() can return 0, check for it */
+ if (spi->irq <= 0) {
+ dev_err(&spi->dev, "no valid irq line defined: irq = %i\n",
+ spi->irq);
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* cross assigns */
+ spi_set_drvdata(spi, priv);
+ priv->spi = spi;
+
+ /* assign name */
+ snprintf(priv->device_name, sizeof(priv->device_name),
+ DEVICE_NAME "-%s", dev_name(&priv->spi->dev));
+
+ /* assign model from of or driver_data */
+ if (of_id)
+ priv->model = (enum mcp25xxfd_model)of_id->data;
+ else
+ priv->model = spi_get_device_id(spi)->driver_data;
+
+ mutex_init(&priv->spi_rxtx_lock);
+
+ ret = mcp25xxfd_clock_init(priv);
+ if (ret)
+ goto out_free;
+
+ /* Configure the SPI bus */
+ spi->bits_per_word = 8;
+ ret = spi_setup(spi);
+ if (ret)
+ goto out_clk;
+
+ priv->power = devm_regulator_get_optional(&spi->dev, "vdd");
+ if (PTR_ERR(priv->power) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out_clk;
+ }
+
+ ret = mcp25xxfd_base_power_enable(priv->power, 1);
+ if (ret)
+ goto out_clk;
+
+ /* this will also enable the MCP25XXFD_CLK_USER_CAN clock */
+ ret = mcp25xxfd_clock_probe(priv);
+ if (ret)
+ goto out_probe;
+
+ /* enable the can controller clock */
+ ret = mcp25xxfd_clock_start(priv, MCP25XXFD_CLK_USER_CAN);
+ if (ret)
+ goto out_probe;
+
+ /* try to identify the can-controller - we need the clock here */
+ ret = mcp25xxfd_can_probe(priv);
+ if (ret)
+ goto out_ctlclk;
+
+ /* add debugfs */
+ mcp25xxfd_debugfs_setup(priv);
+
+ /* disable interrupts */
+ ret = mcp25xxfd_int_enable(priv, false);
+ if (ret)
+ goto out_debugfs;
+
+ /* setup ECC for SRAM */
+ ret = mcp25xxfd_ecc_enable(priv);
+ if (ret)
+ goto out_debugfs;
+
+ /* setting up GPIO */
+ ret = mcp25xxfd_gpio_setup(priv);
+ if (ret)
+ goto out_debugfs;
+
+ /* setting up CAN */
+ ret = mcp25xxfd_can_setup(priv);
+ if (ret)
+ goto out_gpio;
+
+ /* and put controller to sleep by stopping the can clock */
+ ret = mcp25xxfd_clock_stop(priv, MCP25XXFD_CLK_USER_CAN);
+ if (ret)
+ goto out_can;
+
+ dev_info(&spi->dev,
+ "MCP%x successfully initialized.\n", priv->model);
+ return 0;
+
+out_can:
+ mcp25xxfd_can_remove(priv);
+out_gpio:
+ mcp25xxfd_gpio_remove(priv);
+out_debugfs:
+ mcp25xxfd_debugfs_remove(priv);
+out_ctlclk:
+ mcp25xxfd_clock_stop(priv, MCP25XXFD_CLK_USER_CAN);
+out_probe:
+ mcp25xxfd_base_power_enable(priv->power, 0);
+out_clk:
+ mcp25xxfd_clock_release(priv);
+out_free:
+ dev_err(&spi->dev, "Probe failed, err=%d\n", -ret);
+ return ret;
+}
+
+static int mcp25xxfd_base_remove(struct spi_device *spi)
+{
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+
+ /* remove can */
+ mcp25xxfd_can_remove(priv);
+
+ /* remove gpio */
+ mcp25xxfd_gpio_remove(priv);
+
+ /* clear all running clocks */
+ mcp25xxfd_clock_stop(priv, priv->clk_user_mask);
+
+ mcp25xxfd_debugfs_remove(priv);
+
+ mcp25xxfd_base_power_enable(priv->power, 0);
+
+ mcp25xxfd_clock_release(priv);
+
+ return 0;
+}
+
+static int __maybe_unused mcp25xxfd_base_suspend(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+
+ mutex_lock(&priv->clk_user_lock);
+ priv->clk_sleep_mask = priv->clk_user_mask;
+ mutex_unlock(&priv->clk_user_lock);
+
+ /* disable interrupts */
+ mcp25xxfd_int_enable(priv, false);
+
+ /* stop the clocks */
+ mcp25xxfd_clock_stop(priv, priv->clk_sleep_mask);
+
+ /* disable power to controller */
+ return mcp25xxfd_base_power_enable(priv->power, 0);
+}
+
+static int __maybe_unused mcp25xxfd_base_resume(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+ int ret = 0;
+
+ /* enable power to controller */
+ mcp25xxfd_base_power_enable(priv->power, 1);
+
+ /* if there is no sleep mask, then there is nothing to wake */
+ if (!priv->clk_sleep_mask)
+ return 0;
+
+ /* start the clocks */
+ ret = mcp25xxfd_clock_start(priv, priv->clk_sleep_mask);
+ if (ret)
+ return 0;
+
+ /* clear the sleep mask */
+ mutex_lock(&priv->clk_user_lock);
+ priv->clk_sleep_mask = 0;
+ mutex_unlock(&priv->clk_user_lock);
+
+ /* enable the interrupts again */
+ return mcp25xxfd_int_enable(priv, true);
+}
+
+static SIMPLE_DEV_PM_OPS(mcp25xxfd_base_pm_ops, mcp25xxfd_base_suspend,
+ mcp25xxfd_base_resume);
+
+static const struct spi_device_id mcp25xxfd_id_table[] = {
+ {
+ .name = "mcp2517fd",
+ .driver_data = (kernel_ulong_t)CAN_MCP2517FD,
+ },
+ {
+ .name = "mcp2518fd",
+ .driver_data = (kernel_ulong_t)CAN_MCP2518FD,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, mcp25xxfd_id_table);
+
+static struct spi_driver mcp25xxfd_can_driver = {
+ .driver = {
+ .name = DEVICE_NAME,
+ .of_match_table = mcp25xxfd_of_match,
+ .pm = &mcp25xxfd_base_pm_ops,
+ },
+ .id_table = mcp25xxfd_id_table,
+ .probe = mcp25xxfd_base_probe,
+ .remove = mcp25xxfd_base_remove,
+};
+module_spi_driver(mcp25xxfd_can_driver);
+
+MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>");
+MODULE_DESCRIPTION("Microchip 25XXFD CAN driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.h
new file mode 100644
index 000000000000..4559ac60645c
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_base.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_BASE_H
+#define __MCP25XXFD_BASE_H
+
+#include <linux/regulator/consumer.h>
+
+int mcp25xxfd_base_power_enable(struct regulator *reg, int enable);
+
+#endif /* __MCP25XXFD_BASE_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c
new file mode 100644
index 000000000000..5029775009af
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c
@@ -0,0 +1,708 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+/* controller details
+ *
+ * It has 32 FIFOs (of up to 32 CAN-frames).
+ *
+ * There are 4 Fifo types which can get configured:
+ * * TEF - Transmission Event Fifo - which consumes FIFO 0
+ * even if it is not configured
+ * * Tansmission Queue - for up to 32 Frames.
+ * this queue reorders CAN frames to get transmitted following the
+ * typical CAN dominant/recessive rules on the can bus itself.
+ * This FIFO is optional.
+ * * TX FIFO: generic TX fifos that can contain arbitrary data
+ * and which come with a configurable priority for transmission
+ * It is also possible to have the Controller automatically trigger
+ * a transfer when a Filter Rule for a RTR frame matches.
+ * Each of these fifos in principle can get configured for distinct
+ * dlc sizes (8 thru 64 bytes)
+ * * RX FIFO: generic RX fifo which is filled via filter-rules.
+ * Each of these fifos in principle can get configured for distinct
+ * dlc sizes (8 thru 64 bytes)
+ * Unfortunately there is no filter rule that would allow triggering
+ * on different frame sizes, so for all practical purposes the
+ * RX fifos have to be of the same size (unless one wants to experience
+ * lost data).
+ * When a Can Frame is transmitted from the TX Queue or an individual
+ * TX FIFO then a small TEF Frame can get added to the TEF FIFO queue
+ * to log the Transmission of the frame - this includes ID, Flags
+ * (including a custom identifier/index) and the timestamp (see below).
+ *
+ * The controller provides an optional free running counter with a divider
+ * for timestamping of RX frames as well as for TEF entries.
+ */
+
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_base.h"
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_can_debugfs.h"
+#include "mcp25xxfd_can_fifo.h"
+#include "mcp25xxfd_can_int.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_can_tx.h"
+#include "mcp25xxfd_clock.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_int.h"
+#include "mcp25xxfd_priv.h"
+#include "mcp25xxfd_regs.h"
+
+#include <uapi/linux/can/netlink.h>
+
+/* module parameters */
+static unsigned int bw_sharing_log2bits;
+module_param(bw_sharing_log2bits, uint, 0664);
+MODULE_PARM_DESC(bw_sharing_log2bits,
+ "Delay between 2 transmissions in number of arbitration bit times\n");
+static bool enable_edge_filter;
+module_param(enable_edge_filter, bool, 0664);
+MODULE_PARM_DESC(enable_edge_filter,
+ "Enable ISO11898-1:2015 edge_filtering");
+static unsigned int tdc_mode = 2;
+module_param(tdc_mode, uint, 0664);
+MODULE_PARM_DESC(tdc_mode,
+ "Transmitter Delay Mode - 0 = disabled, 1 = fixed, 2 = auto\n");
+static unsigned int tdc_value;
+module_param(tdc_value, uint, 0664);
+MODULE_PARM_DESC(tdc_value,
+ "Transmission Delay Value - range: [0:63] SCLK");
+static int tdc_offset = 64; /* outside of range to use computed values */
+module_param(tdc_offset, int, 0664);
+MODULE_PARM_DESC(tdc_offset,
+ "Transmission Delay offset - range: [-64:63] SCLK");
+
+/* everything related to bit timing */
+static
+const struct can_bittiming_const mcp25xxfd_can_nominal_bittiming_const = {
+ .name = DEVICE_NAME,
+ .tseg1_min = 2,
+ .tseg1_max = BIT(MCP25XXFD_CAN_NBTCFG_TSEG1_BITS),
+ .tseg2_min = 1,
+ .tseg2_max = BIT(MCP25XXFD_CAN_NBTCFG_TSEG2_BITS),
+ .sjw_max = BIT(MCP25XXFD_CAN_NBTCFG_SJW_BITS),
+ .brp_min = 1,
+ .brp_max = BIT(MCP25XXFD_CAN_NBTCFG_BRP_BITS),
+ .brp_inc = 1,
+};
+
+static
+const struct can_bittiming_const mcp25xxfd_can_data_bittiming_const = {
+ .name = DEVICE_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = BIT(MCP25XXFD_CAN_DBTCFG_TSEG1_BITS),
+ .tseg2_min = 1,
+ .tseg2_max = BIT(MCP25XXFD_CAN_DBTCFG_TSEG2_BITS),
+ .sjw_max = BIT(MCP25XXFD_CAN_DBTCFG_SJW_BITS),
+ .brp_min = 1,
+ .brp_max = BIT(MCP25XXFD_CAN_DBTCFG_BRP_BITS),
+ .brp_inc = 1,
+};
+
+static int mcp25xxfd_can_do_set_nominal_bittiming(struct net_device *net)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct can_bittiming *bt = &cpriv->can.bittiming;
+
+ int sjw = bt->sjw;
+ int pseg2 = bt->phase_seg2;
+ int pseg1 = bt->phase_seg1;
+ int propseg = bt->prop_seg;
+ int brp = bt->brp;
+
+ int tseg1 = propseg + pseg1;
+ int tseg2 = pseg2;
+
+ /* calculate nominal bit timing */
+ cpriv->regs.nbtcfg = ((sjw - 1) << MCP25XXFD_CAN_NBTCFG_SJW_SHIFT) |
+ ((tseg2 - 1) << MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT) |
+ ((tseg1 - 1) << MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT) |
+ ((brp - 1) << MCP25XXFD_CAN_NBTCFG_BRP_SHIFT);
+
+ return mcp25xxfd_cmd_write(cpriv->priv->spi, MCP25XXFD_CAN_NBTCFG,
+ cpriv->regs.nbtcfg);
+}
+
+static int mcp25xxfd_can_do_set_data_bittiming(struct net_device *net)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct mcp25xxfd_priv *priv = cpriv->priv;
+ struct can_bittiming *bt = &cpriv->can.data_bittiming;
+ struct spi_device *spi = priv->spi;
+
+ int sjw = bt->sjw;
+ int pseg2 = bt->phase_seg2;
+ int pseg1 = bt->phase_seg1;
+ int propseg = bt->prop_seg;
+ int brp = bt->brp;
+
+ int tseg1 = propseg + pseg1;
+ int tseg2 = pseg2;
+
+ int tdco;
+ int ret;
+
+ /* set up Transmitter delay compensation */
+ cpriv->regs.tdc = 0;
+ /* configure TDC mode */
+ if (tdc_mode < 4)
+ cpriv->regs.tdc = tdc_mode << MCP25XXFD_CAN_TDC_TDCMOD_SHIFT;
+ else
+ cpriv->regs.tdc = MCP25XXFD_CAN_TDC_TDCMOD_AUTO <<
+ MCP25XXFD_CAN_TDC_TDCMOD_SHIFT;
+
+ /* configure TDC offsets */
+ if ((tdc_offset >= -64) && tdc_offset < 64)
+ tdco = tdc_offset;
+ else
+ tdco = clamp_t(int, bt->brp * tseg1, -64, 63);
+ cpriv->regs.tdc |= (tdco << MCP25XXFD_CAN_TDC_TDCO_SHIFT) &
+ MCP25XXFD_CAN_TDC_TDCO_MASK;
+
+ /* configure TDC value */
+ if (tdc_value < 64)
+ cpriv->regs.tdc |= tdc_value << MCP25XXFD_CAN_TDC_TDCV_SHIFT;
+
+ /* enable edge filtering */
+ if (enable_edge_filter)
+ cpriv->regs.tdc |= MCP25XXFD_CAN_TDC_EDGFLTEN;
+
+ /* set TDC */
+ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_TDC, cpriv->regs.tdc);
+ if (ret)
+ return ret;
+
+ /* calculate data bit timing */
+ cpriv->regs.dbtcfg = ((sjw - 1) << MCP25XXFD_CAN_DBTCFG_SJW_SHIFT) |
+ ((tseg2 - 1) << MCP25XXFD_CAN_DBTCFG_TSEG2_SHIFT) |
+ ((tseg1 - 1) << MCP25XXFD_CAN_DBTCFG_TSEG1_SHIFT) |
+ ((brp - 1) << MCP25XXFD_CAN_DBTCFG_BRP_SHIFT);
+
+ return mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_DBTCFG,
+ cpriv->regs.dbtcfg);
+}
+
+int mcp25xxfd_can_get_mode(struct mcp25xxfd_priv *priv, u32 *reg)
+{
+ int ret;
+
+ ret = mcp25xxfd_cmd_read(priv->spi, MCP25XXFD_CAN_CON, reg);
+ if (ret)
+ return ret;
+
+ return (*reg & MCP25XXFD_CAN_CON_OPMOD_MASK) >>
+ MCP25XXFD_CAN_CON_OPMOD_SHIFT;
+}
+
+int mcp25xxfd_can_switch_mode_no_wait(struct mcp25xxfd_priv *priv,
+ u32 *reg, int mode)
+{
+ u32 dummy;
+ int ret;
+
+ /* get the current mode/register - if reg is NULL
+ * when the can controller is not setup yet
+ * typically by calling mcp25xxfd_can_sleep_mode
+ * (this only happens during initialization phase)
+ */
+ if (reg) {
+ if (!*reg) {
+ ret = mcp25xxfd_can_get_mode(priv, reg);
+ if (ret < 0)
+ return ret;
+ }
+ } else {
+ /* alternatively use dummy */
+ dummy = 0;
+ reg = &dummy;
+ }
+
+ /* going out of configuration mode always reset tef.index */
+ if( ((*reg & MCP25XXFD_CAN_CON_OPMOD_MASK) >> MCP25XXFD_CAN_CON_OPMOD_SHIFT) == 4 )
+ priv->cpriv->fifos.tef.index = 0;
+
+ /* compute the effective mode in osc*/
+ *reg &= ~(MCP25XXFD_CAN_CON_REQOP_MASK |
+ MCP25XXFD_CAN_CON_OPMOD_MASK);
+ *reg |= (mode << MCP25XXFD_CAN_CON_REQOP_SHIFT) |
+ (mode << MCP25XXFD_CAN_CON_OPMOD_SHIFT);
+
+ /* if the opmode is sleep then the oscilator will be disabled
+ * and also not ready, so fake this change
+ */
+ if (mode == MCP25XXFD_CAN_CON_MODE_SLEEP)
+ mcp25xxfd_clock_fake_sleep(priv);
+
+ /* request the mode switch */
+ return mcp25xxfd_cmd_write(priv->spi, MCP25XXFD_CAN_CON, *reg);
+}
+
+int mcp25xxfd_can_switch_mode(struct mcp25xxfd_priv *priv, u32 *reg, int mode)
+{
+ int ret, i;
+
+ /* trigger the mode switch itself */
+ ret = mcp25xxfd_can_switch_mode_no_wait(priv, reg, mode);
+ if (ret)
+ return ret;
+
+ /* if we are in now sleep mode then return immediately
+ * the controller does not respond back!
+ */
+ if (mode == MCP25XXFD_CAN_CON_MODE_SLEEP)
+ return 0;
+
+ /* wait for it to stabilize/switch mode
+ * we assume 256 rounds should be enough as this is > 12ms
+ * at 1MHz Can Bus speed without any extra overhead
+ *
+ * The assumption here is that it depends on bus activity
+ * how long it takes the controller to switch modes
+ */
+ for (i = 0; i < 256; i++) {
+ /* get the mode */
+ ret = mcp25xxfd_can_get_mode(priv, reg);
+ if (ret < 0)
+ return ret;
+ /* check that we have reached our mode */
+ if (ret == mode)
+ return 0;
+ }
+
+ dev_err(&priv->spi->dev, "Failed to switch to mode %u in time\n",
+ mode);
+ return -ETIMEDOUT;
+}
+
+static int mcp25xxfd_can_probe_modeswitch(struct mcp25xxfd_priv *priv)
+{
+ u32 mode_data;
+ int ret;
+
+ /* so we should be in config mode now, so move to INT_LOOPBACK */
+ ret = mcp25xxfd_can_switch_mode(priv, &mode_data,
+ MCP25XXFD_CAN_CON_MODE_INT_LOOPBACK);
+ if (ret) {
+ dev_err(&priv->spi->dev,
+ "Failed to switch into loopback mode\n");
+ return ret;
+ }
+
+ /* and back into config mode */
+ ret = mcp25xxfd_can_switch_mode(priv, &mode_data,
+ MCP25XXFD_CAN_CON_MODE_CONFIG);
+ if (ret) {
+ dev_err(&priv->spi->dev,
+ "Failed to switch back to config mode\n");
+ return ret;
+ }
+
+ /* so we have checked basic functionality successfully */
+ return 0;
+}
+
+int mcp25xxfd_can_sleep_mode(struct mcp25xxfd_priv *priv)
+{
+ return mcp25xxfd_can_switch_mode(priv, NULL,
+ MCP25XXFD_CAN_CON_MODE_SLEEP);
+}
+
+int mcp25xxfd_can_probe(struct mcp25xxfd_priv *priv)
+{
+ struct spi_device *spi = priv->spi;
+ u32 mode_data;
+ int mode, ret;
+
+ /* read TXQCON - the TXEN bit should always read as 1 */
+ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_CAN_TXQCON, &mode_data);
+ if (ret)
+ return ret;
+ if ((mode_data & MCP25XXFD_CAN_TXQCON_TXEN) == 0) {
+ dev_err(&spi->dev,
+ "Register TXQCON does not have bit TXEN set - reads as %08x - this may be a problem with spi bus signal quality - try reducing spi-clock speed if this can get reproduced",
+ mode_data);
+ return -EINVAL;
+ }
+
+ /* try to get the current mode */
+ mode = mcp25xxfd_can_get_mode(priv, &mode_data);
+ if (mode < 0)
+ return mode;
+
+ /* we would expect to be in config mode, as a SPI-reset should
+ * have moved us into config mode.
+ * But then the documentation says that SPI-reset may only work
+ * reliably when already in config mode
+ */
+
+ /* so if we are in config mode then everything is fine
+ * and we check that a mode switch works propperly
+ */
+ if (mode == MCP25XXFD_CAN_CON_MODE_CONFIG) {
+ /* all mode switches require bus idle condition. Power on default bit rate setting is about
+ * 500kbps @ 40MHz. This is OK for all real bus speeds up to 500kbps and SYSCLK=40MHz. But
+ * probe may fail when real bus speed is 1Mbps and bus load is high (>50%). As well
+ * probe may fail with SYSCLK=20MHz and high bus load on 500kbps bus.
+ * Switching to >=1Mbps bitrate @ 20MHz to avoid this issue for SYSCLK>=20MHz and
+ * all standard arbitration bitrates */
+ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_NBTCFG, (0 << MCP25XXFD_CAN_NBTCFG_BRP_SHIFT) |
+ (13 << MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT) |
+ (4 << MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT) |
+ (1 << MCP25XXFD_CAN_NBTCFG_SJW_SHIFT));
+
+ if (ret)
+ return ret;
+
+ return mcp25xxfd_can_probe_modeswitch(priv);
+ } else {
+ dev_warn(&spi->dev, "Not in CONFIG mode.\n");
+ }
+
+ /* if the bitfield is 0 then there is something is wrong */
+ if (!mode_data) {
+ dev_err(&spi->dev,
+ "got controller config register reading as 0\n");
+ return -EINVAL;
+ }
+
+ /* any other mode is unexpected */
+ dev_err(&spi->dev,
+ "Found controller in unexpected mode %i - register reads as %08x\n",
+ mode, mode_data);
+
+ /* so try to move to config mode
+ * if this fails, then everything is lost and the controller
+ * is not identified
+ * This action MAY be destructive if a different device is connected
+ * but note that the first hurdle (oscillator) was already
+ * successful - so we should be safe...
+ */
+ ret = mcp25xxfd_can_switch_mode(priv, &mode_data,
+ MCP25XXFD_CAN_CON_MODE_CONFIG);
+ if (ret) {
+ dev_err(&priv->spi->dev,
+ "Mode did not switch to config as expected - could not identify controller - register reads as %08x\n",
+ mode_data);
+ return -EINVAL;
+ }
+ /* check that modeswitch is really working */
+ return mcp25xxfd_can_probe_modeswitch(priv);
+}
+
+static int mcp25xxfd_can_config(struct net_device *net)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct mcp25xxfd_priv *priv = cpriv->priv;
+ struct spi_device *spi = priv->spi;
+ int ret;
+
+ /* setup value of con_register */
+ cpriv->regs.con = MCP25XXFD_CAN_CON_STEF; /* enable TEF, disable TXQ */
+
+ /* transmission bandwidth sharing bits */
+ if (bw_sharing_log2bits > 12)
+ bw_sharing_log2bits = 12;
+ cpriv->regs.con |= bw_sharing_log2bits <<
+ MCP25XXFD_CAN_CON_TXBWS_SHIFT;
+
+ /* non iso FD mode */
+ if (!(cpriv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO))
+ cpriv->regs.con |= MCP25XXFD_CAN_CON_ISOCRCEN;
+
+ /* one shot */
+ if (cpriv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ cpriv->regs.con |= MCP25XXFD_CAN_CON_RTXAT;
+
+ /* apply it now together with a mode switch */
+ ret = mcp25xxfd_can_switch_mode(cpriv->priv, &cpriv->regs.con,
+ MCP25XXFD_CAN_CON_MODE_CONFIG);
+ if (ret)
+ return 0;
+
+ /* time stamp control register - 1ns resolution */
+ cpriv->regs.tscon = 0;
+ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_TBC, 0);
+ if (ret)
+ return ret;
+
+ cpriv->regs.tscon = MCP25XXFD_CAN_TSCON_TBCEN |
+ ((cpriv->can.clock.freq / 1000000)
+ << MCP25XXFD_CAN_TSCON_TBCPRE_SHIFT);
+ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_TSCON, cpriv->regs.tscon);
+ if (ret)
+ return ret;
+
+ /* setup fifos */
+ ret = mcp25xxfd_can_fifo_setup(cpriv);
+ if (ret)
+ return ret;
+
+ /* setup can bittiming now - the do_set_bittiming methods
+ * are not used as they get callled before open
+ */
+ ret = mcp25xxfd_can_do_set_nominal_bittiming(net);
+ if (ret)
+ return ret;
+ ret = mcp25xxfd_can_do_set_data_bittiming(net);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+/* mode setting */
+static int mcp25xxfd_can_do_set_mode(struct net_device *net,
+ enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+/* binary error counters */
+static int mcp25xxfd_can_get_berr_counter(const struct net_device *net,
+ struct can_berr_counter *bec)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+
+ bec->txerr = (cpriv->status.trec & MCP25XXFD_CAN_TREC_TEC_MASK) >>
+ MCP25XXFD_CAN_TREC_TEC_SHIFT;
+ bec->rxerr = (cpriv->status.trec & MCP25XXFD_CAN_TREC_REC_MASK) >>
+ MCP25XXFD_CAN_TREC_REC_SHIFT;
+
+ return 0;
+}
+
+static int mcp25xxfd_can_open(struct net_device *net)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct spi_device *spi = cpriv->priv->spi;
+ int ret;
+
+ ret = open_candev(net);
+ if (ret) {
+ netdev_err(net, "unable to set initial baudrate!\n");
+ return ret;
+ }
+
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ /* clear those statistics */
+ memset(&cpriv->stats, 0, sizeof(cpriv->stats));
+#endif
+
+ /* request an IRQ but keep disabled for now */
+ ret = request_threaded_irq(spi->irq, NULL,
+ mcp25xxfd_can_int,
+ IRQF_ONESHOT | IRQF_TRIGGER_LOW,
+ cpriv->priv->device_name, cpriv);
+ if (ret) {
+ dev_err(&spi->dev, "failed to acquire irq %d - %i\n",
+ spi->irq, ret);
+ goto out_candev;
+ }
+ disable_irq(spi->irq);
+ cpriv->irq.allocated = true;
+ cpriv->irq.enabled = false;
+
+ /* enable power to the transceiver */
+ ret = mcp25xxfd_base_power_enable(cpriv->transceiver, 1);
+ if (ret)
+ goto out_irq;
+
+ /* enable clock (so that spi works) */
+ ret = mcp25xxfd_clock_start(cpriv->priv, MCP25XXFD_CLK_USER_CAN);
+ if (ret)
+ goto out_transceiver;
+
+ /* configure controller for reception */
+ ret = mcp25xxfd_can_config(net);
+ if (ret)
+ goto out_canclock;
+
+ /* setting up state */
+ cpriv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* enable interrupts */
+ ret = mcp25xxfd_int_enable(cpriv->priv, true);
+ if (ret)
+ goto out_canconfig;
+
+ /* switch to active mode */
+ ret = mcp25xxfd_can_switch_mode(cpriv->priv, &cpriv->regs.con,
+ (net->mtu == CAN_MTU) ?
+ MCP25XXFD_CAN_CON_MODE_CAN2_0 :
+ MCP25XXFD_CAN_CON_MODE_MIXED);
+ if (ret)
+ goto out_int;
+
+ /* start the tx_queue */
+ mcp25xxfd_can_tx_queue_manage(cpriv,
+ MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED);
+
+ return 0;
+
+out_int:
+ mcp25xxfd_int_enable(cpriv->priv, false);
+out_canconfig:
+ mcp25xxfd_can_fifo_release(cpriv);
+out_canclock:
+ mcp25xxfd_clock_stop(cpriv->priv, MCP25XXFD_CLK_USER_CAN);
+out_transceiver:
+ mcp25xxfd_base_power_enable(cpriv->transceiver, 0);
+out_irq:
+ free_irq(spi->irq, cpriv);
+ cpriv->irq.allocated = false;
+ cpriv->irq.enabled = false;
+out_candev:
+ close_candev(net);
+ return ret;
+}
+
+static void mcp25xxfd_can_shutdown(struct mcp25xxfd_can_priv *cpriv)
+{
+ /* switch us to CONFIG mode - this disables the controller */
+ mcp25xxfd_can_switch_mode(cpriv->priv, &cpriv->regs.con,
+ MCP25XXFD_CAN_CON_MODE_CONFIG);
+}
+
+static int mcp25xxfd_can_stop(struct net_device *net)
+{
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct mcp25xxfd_priv *priv = cpriv->priv;
+ struct spi_device *spi = priv->spi;
+
+ /* disable inerrupts on controller */
+ mcp25xxfd_int_enable(cpriv->priv, false);
+
+ /* stop transmit queue */
+ mcp25xxfd_can_tx_queue_manage(cpriv,
+ MCP25XXFD_CAN_TX_QUEUE_STATE_STOPPED);
+
+ /* release fifos and debugfs */
+ mcp25xxfd_can_fifo_release(cpriv);
+
+ /* shutdown the can controller */
+ mcp25xxfd_can_shutdown(cpriv);
+
+ /* stop the clock */
+ mcp25xxfd_clock_stop(cpriv->priv, MCP25XXFD_CLK_USER_CAN);
+
+ /* and disable the transceiver */
+ mcp25xxfd_base_power_enable(cpriv->transceiver, 0);
+
+ /* disable interrupt on host */
+ free_irq(spi->irq, cpriv);
+ cpriv->irq.allocated = false;
+ cpriv->irq.enabled = false;
+
+ /* close the can_decice */
+ close_candev(net);
+
+ return 0;
+}
+
+static const struct net_device_ops mcp25xxfd_netdev_ops = {
+ .ndo_open = mcp25xxfd_can_open,
+ .ndo_stop = mcp25xxfd_can_stop,
+ .ndo_start_xmit = mcp25xxfd_can_tx_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+/* probe and remove */
+int mcp25xxfd_can_setup(struct mcp25xxfd_priv *priv)
+{
+ struct spi_device *spi = priv->spi;
+ struct mcp25xxfd_can_priv *cpriv;
+ struct net_device *net;
+ struct regulator *transceiver;
+ int ret;
+
+ /* get transceiver power regulator*/
+ transceiver = devm_regulator_get_optional(&spi->dev,
+ "xceiver");
+ if (PTR_ERR(transceiver) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ /* allocate can device */
+ net = alloc_candev(sizeof(*cpriv), TX_ECHO_SKB_MAX);
+ if (!net)
+ return -ENOMEM;
+
+ /* and do some cross-asignments */
+ cpriv = netdev_priv(net);
+ cpriv->priv = priv;
+ priv->cpriv = cpriv;
+
+ /* setup network */
+ SET_NETDEV_DEV(net, &spi->dev);
+ net->netdev_ops = &mcp25xxfd_netdev_ops;
+ net->flags |= IFF_ECHO;
+
+ /* assign transceiver */
+ cpriv->transceiver = transceiver;
+
+ /* setup can */
+ cpriv->can.clock.freq = priv->clock_freq;
+ cpriv->can.bittiming_const =
+ &mcp25xxfd_can_nominal_bittiming_const;
+ cpriv->can.data_bittiming_const =
+ &mcp25xxfd_can_data_bittiming_const;
+ /* we are not setting bit-timing methods here as they get
+ * called by the framework before open so the controller is
+ * still in sleep mode, which does not help
+ * things are configured in open instead
+ */
+ cpriv->can.do_set_mode =
+ mcp25xxfd_can_do_set_mode;
+ cpriv->can.do_get_berr_counter =
+ mcp25xxfd_can_get_berr_counter;
+ cpriv->can.ctrlmode_supported =
+ CAN_CTRLMODE_FD |
+ CAN_CTRLMODE_FD_NON_ISO |
+ CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_BERR_REPORTING |
+ CAN_CTRLMODE_ONE_SHOT;
+
+ ret = register_candev(net);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to register can device\n");
+ goto out;
+ }
+
+ mcp25xxfd_can_debugfs_setup(cpriv);
+
+ return 0;
+out:
+ free_candev(net);
+ priv->cpriv = NULL;
+
+ return ret;
+}
+
+void mcp25xxfd_can_remove(struct mcp25xxfd_priv *priv)
+{
+ if (priv->cpriv) {
+ unregister_candev(priv->cpriv->can.dev);
+ free_candev(priv->cpriv->can.dev);
+ priv->cpriv = NULL;
+ }
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.h
new file mode 100644
index 000000000000..6fca746d2dd5
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_H
+#define __MCP25XXFD_CAN_H
+
+#include "mcp25xxfd_can_debugfs.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_priv.h"
+#include "mcp25xxfd_regs.h"
+
+/* get the optimal controller target mode */
+static inline
+int mcp25xxfd_can_targetmode(struct mcp25xxfd_can_priv *cpriv)
+{
+ return (cpriv->can.dev->mtu == CAN_MTU) ?
+ MCP25XXFD_CAN_CON_MODE_CAN2_0 : MCP25XXFD_CAN_CON_MODE_MIXED;
+}
+
+static inline
+void mcp25xxfd_can_queue_frame(struct mcp25xxfd_can_priv *cpriv,
+ s32 fifo, u32 ts, bool is_rx)
+{
+ int idx = cpriv->fifos.submit_queue_count;
+
+ cpriv->fifos.submit_queue[idx].fifo = fifo;
+ cpriv->fifos.submit_queue[idx].ts = ts;
+ cpriv->fifos.submit_queue[idx].is_rx = is_rx;
+
+ cpriv->fifos.submit_queue_count++;
+}
+
+/* get the current controller mode */
+int mcp25xxfd_can_get_mode(struct mcp25xxfd_priv *priv, u32 *reg);
+
+/* to put us to sleep fully we need the CAN controller to enter sleep mode */
+int mcp25xxfd_can_sleep_mode(struct mcp25xxfd_priv *priv);
+
+/* switch controller mode */
+int mcp25xxfd_can_switch_mode_no_wait(struct mcp25xxfd_priv *priv,
+ u32 *reg, int mode);
+int mcp25xxfd_can_switch_mode(struct mcp25xxfd_priv *priv,
+ u32 *reg, int mode);
+
+/* probe the can controller */
+int mcp25xxfd_can_probe(struct mcp25xxfd_priv *priv);
+
+/* setup and the can controller net interface */
+int mcp25xxfd_can_setup(struct mcp25xxfd_priv *priv);
+void mcp25xxfd_can_remove(struct mcp25xxfd_priv *priv);
+
+#endif /* __MCP25XXFD_CAN_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.c
new file mode 100644
index 000000000000..929a0c182c04
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/dcache.h>
+#include <linux/debugfs.h>
+#include "mcp25xxfd_can_debugfs.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_can_tx.h"
+
+static void mcp25xxfd_can_debugfs_regs(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("regs", root);
+
+ debugfs_create_x32("con", 0444, dir, &cpriv->regs.con);
+ debugfs_create_x32("tdc", 0444, dir, &cpriv->regs.tdc);
+ debugfs_create_x32("tscon", 0444, dir, &cpriv->regs.tscon);
+ debugfs_create_x32("tefcon", 0444, dir, &cpriv->regs.tscon);
+ debugfs_create_x32("nbtcfg", 0444, dir, &cpriv->regs.nbtcfg);
+ debugfs_create_x32("dbtcfg", 0444, dir, &cpriv->regs.dbtcfg);
+}
+
+static void mcp25xxfd_can_debugfs_status(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("status", root);
+
+ debugfs_create_x32("intf", 0444, dir, &cpriv->status.intf);
+ debugfs_create_x32("rx_if", 0444, dir, &cpriv->status.rxif);
+ debugfs_create_x32("tx_if", 0444, dir, &cpriv->status.txif);
+ debugfs_create_x32("rx_ovif", 0444, dir, &cpriv->status.rxovif);
+ debugfs_create_x32("tx_atif", 0444, dir, &cpriv->status.txatif);
+ debugfs_create_x32("tx_req", 0444, dir, &cpriv->status.txreq);
+ debugfs_create_x32("trec", 0444, dir, &cpriv->status.trec);
+}
+
+static void mcp25xxfd_can_debugfs_stats(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("stats", root);
+ char name[32];
+ u64 *data;
+ int i;
+
+# define DEBUGFS_CREATE(name, var) debugfs_create_u64(name, 0444, dir, \
+ &cpriv->stats.var)
+ DEBUGFS_CREATE("irq_calls", irq_calls);
+ DEBUGFS_CREATE("irq_loops", irq_loops);
+ DEBUGFS_CREATE("irq_thread_rescheduled", irq_thread_rescheduled);
+
+ DEBUGFS_CREATE("int_system_error", int_serr_count);
+ DEBUGFS_CREATE("int_system_error_tx", int_serr_tx_count);
+ DEBUGFS_CREATE("int_system_error_rx", int_serr_rx_count);
+ DEBUGFS_CREATE("int_mode_switch", int_mod_count);
+ DEBUGFS_CREATE("int_rx", int_rx_count);
+ DEBUGFS_CREATE("int_tx_attempt", int_txat_count);
+ DEBUGFS_CREATE("int_tef", int_tef_count);
+ DEBUGFS_CREATE("int_rx_overflow", int_rxov_count);
+ DEBUGFS_CREATE("int_ecc_error", int_ecc_count);
+ DEBUGFS_CREATE("int_rx_invalid_message", int_ivm_count);
+ DEBUGFS_CREATE("int_crcerror", int_cerr_count);
+
+ DEBUGFS_CREATE("tef_reads", tef_reads);
+ DEBUGFS_CREATE("tef_read_splits", tef_read_splits);
+
+ DEBUGFS_CREATE("tx_frames_fd", tx_fd_count);
+ DEBUGFS_CREATE("tx_frames_brs", tx_brs_count);
+
+ DEBUGFS_CREATE("rx_reads", rx_reads);
+ DEBUGFS_CREATE("rx_reads_prefetched_too_few",
+ rx_reads_prefetched_too_few);
+ DEBUGFS_CREATE("rx_reads_prefetched_too_few_bytes",
+ rx_reads_prefetched_too_few_bytes);
+ DEBUGFS_CREATE("rx_reads_prefetched_too_many",
+ rx_reads_prefetched_too_many);
+ DEBUGFS_CREATE("rx_reads_prefetched_too_many_bytes",
+ rx_reads_prefetched_too_many_bytes);
+ DEBUGFS_CREATE("rx_single_reads", rx_single_reads);
+ DEBUGFS_CREATE("rx_bulk_reads", rx_bulk_reads);
+
+ for (i = 0; i < MCP25XXFD_CAN_RX_BULK_READ_BINS - 1; i++) {
+ snprintf(name, sizeof(name), "rx_bulk_reads_%i", i + 1);
+ data = &cpriv->stats.rx_bulk_read_sizes[i];
+ debugfs_create_u64(name, 0444, dir, data);
+ }
+ snprintf(name, sizeof(name), "rx_bulk_reads_%i+", i + 1);
+ debugfs_create_u64(name, 0444, dir,
+ &cpriv->stats.rx_bulk_read_sizes[i]);
+
+ if (cpriv->can.dev->mtu == CANFD_MTU)
+ debugfs_create_u32("rx_reads_prefetch_predicted_len", 0444,
+ dir, &cpriv->rx_history.predicted_len);
+#undef DEBUGFS_CREATE
+}
+
+static void mcp25xxfd_can_debugfs_tef(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("tef", root);
+
+ debugfs_create_u32("count", 0444, dir, &cpriv->fifos.tef.count);
+ debugfs_create_u32("size", 0444, dir, &cpriv->fifos.tef.size);
+}
+
+static void mcp25xxfd_can_debugfs_fifo_info(struct mcp25xxfd_fifo_info *info,
+ int index, struct dentry *root)
+{
+ struct dentry *dir;
+ char name[4];
+
+ snprintf(name, sizeof(name), "%02i", index);
+ dir = debugfs_create_dir(name, root);
+
+ debugfs_create_u32("is_rx", 0444, dir, &info->is_rx);
+ debugfs_create_x32("offset", 0444, dir, &info->offset);
+ debugfs_create_u32("priority", 0444, dir, &info->priority);
+
+ debugfs_create_u64("use_count", 0444, dir, &info->use_count);
+}
+
+static void mcp25xxfd_can_debugfs_fifos(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("fifos", root);
+ int i;
+
+ /* now present all fifos - there is no fifo 0 */
+ for (i = 1; i < 32; i++)
+ mcp25xxfd_can_debugfs_fifo_info(&cpriv->fifos.info[i], i, dir);
+}
+
+static void mcp25xxfd_can_debugfs_rxtx_fifos(struct mcp25xxfd_fifo *d,
+ struct dentry *root)
+{
+ int i, f;
+ char name[4];
+ char link[32];
+
+ debugfs_create_u32("count", 0444, root, &d->count);
+ debugfs_create_u32("size", 0444, root, &d->size);
+ debugfs_create_u32("start", 0444, root, &d->start);
+
+ for (f = d->start, i = 0; i < d->count; f++, i++) {
+ snprintf(name, sizeof(name), "%02i", i);
+ snprintf(link, sizeof(link), "../fifos/%02i", f);
+
+ debugfs_create_symlink(name, root, link);
+ }
+}
+
+static void mcp25xxfd_can_debugfs_rx_fifos(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("rx_fifos", root);
+
+ mcp25xxfd_can_debugfs_rxtx_fifos(&cpriv->fifos.rx, dir);
+}
+
+static void mcp25xxfd_can_debugfs_tx_fifos(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct dentry *dir = debugfs_create_dir("tx_fifos", root);
+
+ mcp25xxfd_can_debugfs_rxtx_fifos(&cpriv->fifos.rx, dir);
+}
+
+static void mcp25xxfd_can_debugfs_tx_queue(struct mcp25xxfd_can_priv *cpriv,
+ struct dentry *root)
+{
+ struct mcp25xxfd_tx_spi_message_queue *queue = cpriv->fifos.tx_queue;
+ struct dentry *dir;
+
+ if (!queue)
+ return;
+
+ dir = debugfs_create_dir("tx_queue", root);
+
+ debugfs_create_u32("state", 0444, dir, &queue->state);
+ debugfs_create_x32("fifos_idle", 0444, dir, &queue->idle);
+ debugfs_create_x32("fifos_in_fill_fifo_transfer",
+ 0444, dir, &queue->in_fill_fifo_transfer);
+ debugfs_create_x32("fifos_in_trigger_fifo_transfer",
+ 0444, dir, &queue->in_trigger_fifo_transfer);
+ debugfs_create_x32("fifos_in_can_transfer",
+ 0444, dir, &queue->in_can_transfer);
+ debugfs_create_x32("fifos_transferred",
+ 0444, dir, &queue->transferred);
+}
+
+void mcp25xxfd_can_debugfs_remove(struct mcp25xxfd_can_priv *cpriv)
+{
+ debugfs_remove_recursive(cpriv->debugfs_dir);
+ cpriv->debugfs_dir = NULL;
+}
+
+void mcp25xxfd_can_debugfs_setup(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct dentry *root;
+
+ /* remove first as we get called during probe and also
+ * when the can_device is configured/removed
+ */
+ mcp25xxfd_can_debugfs_remove(cpriv);
+
+ root = debugfs_create_dir("can", cpriv->priv->debugfs_dir);
+ cpriv->debugfs_dir = root;
+
+ mcp25xxfd_can_debugfs_regs(cpriv, root);
+ mcp25xxfd_can_debugfs_stats(cpriv, root);
+ mcp25xxfd_can_debugfs_status(cpriv, root);
+ mcp25xxfd_can_debugfs_tef(cpriv, root);
+ mcp25xxfd_can_debugfs_fifos(cpriv, root);
+ mcp25xxfd_can_debugfs_rx_fifos(cpriv, root);
+ mcp25xxfd_can_debugfs_tx_fifos(cpriv, root);
+ mcp25xxfd_can_debugfs_tx_queue(cpriv, root);
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.h
new file mode 100644
index 000000000000..a8391370d4bf
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_debugfs.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_DEBUGFS_H
+#define __MCP25XXFD_CAN_DEBUGFS_H
+
+#include "mcp25xxfd_can_priv.h"
+
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+
+#include <linux/debugfs.h>
+
+#define MCP25XXFD_DEBUGFS_INCR(counter) ((counter)++)
+#define MCP25XXFD_DEBUGFS_ADD(counter, val) ((counter) += (val))
+#define MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, counter) \
+ (((cpriv)->stats.counter)++)
+#define MCP25XXFD_DEBUGFS_STATS_ADD(cpriv, counter, val) \
+ (((cpriv)->stats.counter) += (val))
+
+void mcp25xxfd_can_debugfs_setup(struct mcp25xxfd_can_priv *cpriv);
+void mcp25xxfd_can_debugfs_remove(struct mcp25xxfd_can_priv *cpriv);
+
+#else /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+
+#define MCP25XXFD_DEBUGFS_INCR(counter)
+#define MCP25XXFD_DEBUGFS_ADD(counter, val)
+#define MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, counter)
+#define MCP25XXFD_DEBUGFS_STATS_ADD(cpriv, counter, val)
+
+static inline
+void mcp25xxfd_can_debugfs_setup(struct mcp25xxfd_can_priv *cpriv)
+{
+}
+
+static inline
+void mcp25xxfd_can_debugfs_remove(struct mcp25xxfd_can_priv *cpriv)
+{
+}
+
+#endif /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+#endif /* __MCP25XXFD_CAN_DEBUGFS_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.c
new file mode 100644
index 000000000000..990c3a77da9d
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+/* here we define and configure the fifo layout */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_can_fifo.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_can_tx.h"
+#include "mcp25xxfd_cmd.h"
+
+/* some controller parameters are currently not configurable via netlink
+ * so we allow to control them via module parameters (that can changed
+ * in /sys if needed) - theses are only needed during setup if the can_device
+ */
+static unsigned int tx_fifos;
+module_param(tx_fifos, uint, 0664);
+MODULE_PARM_DESC(tx_fifos,
+ "Number of tx-fifos to configure - recommended value is < 7\n");
+
+static bool three_shot;
+module_param(three_shot, bool, 0664);
+MODULE_PARM_DESC(three_shot, "Use 3 shots when one-shot is requested");
+
+static int mcp25xxfd_can_fifo_get_address(struct mcp25xxfd_can_priv *cpriv)
+{
+ int fifo, ret;
+
+ /* we need to move out of config mode to force address computation */
+ ret = mcp25xxfd_can_switch_mode(cpriv->priv, &cpriv->regs.con,
+ MCP25XXFD_CAN_CON_MODE_INT_LOOPBACK);
+ if (ret)
+ return ret;
+
+ /* and get back into config mode */
+ ret = mcp25xxfd_can_switch_mode(cpriv->priv, &cpriv->regs.con,
+ MCP25XXFD_CAN_CON_MODE_CONFIG);
+ if (ret)
+ return ret;
+
+ /* read address and config back in */
+ for (fifo = 1; fifo < 32; fifo++) {
+ ret = mcp25xxfd_cmd_read(cpriv->priv->spi,
+ MCP25XXFD_CAN_FIFOUA(fifo),
+ &cpriv->fifos.info[fifo].offset);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_fifo_setup_config(struct mcp25xxfd_can_priv *cpriv,
+ struct mcp25xxfd_fifo *desc,
+ u32 flags, u32 flags_last)
+{
+ u32 val;
+ int i, p, f, c, ret;
+
+ /* now setup the fifos themselves */
+ for (i = 0, f = desc->start, c = desc->count, p = 31;
+ c > 0; i++, f++, p--, c--) {
+ /* select the effective value */
+ val = (c > 1) ? flags : flags_last;
+
+ /* are we in tx mode */
+ if (flags & MCP25XXFD_CAN_FIFOCON_TXEN) {
+ cpriv->fifos.info[f].is_rx = false;
+ cpriv->fifos.info[f].priority = p;
+ val |= (p << MCP25XXFD_CAN_FIFOCON_TXPRI_SHIFT);
+ } else {
+ cpriv->fifos.info[f].is_rx = true;
+ }
+
+ /* write the config to the controller in one go */
+ ret = mcp25xxfd_cmd_write(cpriv->priv->spi,
+ MCP25XXFD_CAN_FIFOCON(f), val);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_fifo_setup_tx(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 tx_flags = MCP25XXFD_CAN_FIFOCON_FRESET | /* reset FIFO */
+ MCP25XXFD_CAN_FIFOCON_TXEN | /* a tx FIFO */
+ MCP25XXFD_CAN_FIFOCON_TXATIE | /* state in txatif */
+ (cpriv->fifos.payload_mode <<
+ MCP25XXFD_CAN_FIFOCON_PLSIZE_SHIFT) | /* paylod size */
+ (0 << MCP25XXFD_CAN_FIFOCON_FSIZE_SHIFT); /* 1 FIFO deep */
+
+ /* handle oneshot/three-shot */
+ if (cpriv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ if (three_shot)
+ tx_flags |= MCP25XXFD_CAN_FIFOCON_TXAT_THREE_SHOT <<
+ MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT;
+ else
+ tx_flags |= MCP25XXFD_CAN_FIFOCON_TXAT_ONE_SHOT <<
+ MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT;
+ else
+ tx_flags |= MCP25XXFD_CAN_FIFOCON_TXAT_UNLIMITED <<
+ MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT;
+
+ return mcp25xxfd_can_fifo_setup_config(cpriv, &cpriv->fifos.tx,
+ tx_flags, tx_flags);
+}
+
+static int mcp25xxfd_can_fifo_setup_rx(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 rx_flags = MCP25XXFD_CAN_FIFOCON_FRESET | /* reset FIFO */
+ MCP25XXFD_CAN_FIFOCON_RXTSEN | /* RX timestamps */
+ MCP25XXFD_CAN_FIFOCON_TFERFFIE | /* FIFO Full */
+ MCP25XXFD_CAN_FIFOCON_TFHRFHIE | /* FIFO Half Full*/
+ MCP25XXFD_CAN_FIFOCON_TFNRFNIE | /* FIFO not empty */
+ (cpriv->fifos.payload_mode <<
+ MCP25XXFD_CAN_FIFOCON_PLSIZE_SHIFT) |
+ (0 << MCP25XXFD_CAN_FIFOCON_FSIZE_SHIFT); /* 1 FIFO deep */
+ /* enable overflow int on last fifo */
+ u32 rx_flags_last = rx_flags | MCP25XXFD_CAN_FIFOCON_RXOVIE;
+
+ return mcp25xxfd_can_fifo_setup_config(cpriv, &cpriv->fifos.rx,
+ rx_flags, rx_flags_last);
+}
+
+static int mcp25xxfd_can_fifo_setup_rxfilter(struct mcp25xxfd_can_priv *cpriv)
+{
+ u8 filter_con[32];
+ int c, f;
+
+ /* clear the filters and filter mappings for all filters */
+ memset(filter_con, 0, sizeof(filter_con));
+
+ /* and now set up the rx filters */
+ for (c = 0, f = cpriv->fifos.rx.start; c < cpriv->fifos.rx.count;
+ c++, f++) {
+ /* set up filter config - we can use the mask of filter 0 */
+ filter_con[c] = MCP25XXFD_CAN_FLTCON_FLTEN(0) |
+ (f << MCP25XXFD_CAN_FLTCON_SHIFT(0));
+ }
+
+ /* and set up filter control */
+ return mcp25xxfd_cmd_write_regs(cpriv->priv->spi,
+ MCP25XXFD_CAN_FLTCON(0),
+ (u32 *)filter_con, sizeof(filter_con));
+}
+
+static int mcp25xxfd_can_fifo_compute(struct mcp25xxfd_can_priv *cpriv)
+{
+ int tef_memory_used, tx_memory_used, rx_memory_available;
+
+ /* default settings as per MTU/CANFD */
+ switch (cpriv->can.dev->mtu) {
+ case CAN_MTU:
+ /* mtu is 8 */
+ cpriv->fifos.payload_size = 8;
+ cpriv->fifos.payload_mode = MCP25XXFD_CAN_TXQCON_PLSIZE_8;
+
+ /* 6 tx fifos */
+ cpriv->fifos.tx.count = 6;
+
+ break;
+ case CANFD_MTU:
+ /* wish there was a way to have hw filters
+ * that can separate based on length ...
+ */
+ /* MTU is 64 */
+ cpriv->fifos.payload_size = 64;
+ cpriv->fifos.payload_mode = MCP25XXFD_CAN_TXQCON_PLSIZE_64;
+
+ /* 6 tx fifos */
+ cpriv->fifos.tx.count = 6;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* compute effective sizes */
+ cpriv->fifos.tef.size = sizeof(struct mcp25xxfd_can_obj_tef);
+ cpriv->fifos.tx.size = sizeof(struct mcp25xxfd_can_obj_tx) +
+ cpriv->fifos.payload_size;
+ cpriv->fifos.rx.size = sizeof(struct mcp25xxfd_can_obj_rx) +
+ cpriv->fifos.payload_size;
+
+ /* if defined as a module parameter modify the number of tx_fifos */
+ if (tx_fifos) {
+ netdev_info(cpriv->can.dev,
+ "Using %i tx-fifos as per module parameter\n",
+ tx_fifos);
+ cpriv->fifos.tx.count = tx_fifos;
+ if (tx_fifos > 6)
+ netdev_info(cpriv->can.dev,
+ "You may trigger a bug where during a spi transfer bit 7, 15, 23 or 31 of TXREQ may flip due to CAN bus activity or similar so the recommended value is < 7\n");
+ }
+
+ /* there can be at the most 30 tx fifos (TEF and at least 1 RX fifo */
+ if (cpriv->fifos.tx.count > 30) {
+ netdev_err(cpriv->can.dev,
+ "There is an absolute maximum of 30 tx-fifos\n");
+ return -EINVAL;
+ }
+
+ /* set tef fifos to the number of tx fifos */
+ cpriv->fifos.tef.count = cpriv->fifos.tx.count;
+
+ /* compute size of the tx fifos and TEF */
+ tx_memory_used = cpriv->fifos.tx.count * cpriv->fifos.tx.size;
+ tef_memory_used = cpriv->fifos.tef.count * cpriv->fifos.tef.size;
+
+ /* calculate evailable memory for RX_fifos */
+ rx_memory_available = MCP25XXFD_SRAM_SIZE - tx_memory_used -
+ tef_memory_used;
+
+ /* we need at least one RX Frame */
+ if (rx_memory_available < cpriv->fifos.rx.size) {
+ netdev_err(cpriv->can.dev,
+ "Configured %i tx-fifos exceeds available memory already\n",
+ cpriv->fifos.tx.count);
+ return -EINVAL;
+ }
+
+ /* calculate possible amount of RX fifos */
+ cpriv->fifos.rx.count = rx_memory_available / cpriv->fifos.rx.size;
+
+ /* so now calculate effective number of rx-fifos
+ * there are only 31 fifos available in total,
+ * so we need to limit ourselves
+ */
+ if (cpriv->fifos.rx.count + cpriv->fifos.tx.count > 31)
+ cpriv->fifos.rx.count = 31 - cpriv->fifos.tx.count;
+
+ /* define the layout now that we have gotten everything */
+ cpriv->fifos.tx.start = 1;
+ cpriv->fifos.rx.start = cpriv->fifos.tx.start + cpriv->fifos.tx.count;
+
+ return 0;
+}
+
+static int mcp25xxfd_can_fifo_clear_regs(struct mcp25xxfd_can_priv *cpriv,
+ u32 start, u32 end)
+{
+ size_t len = end - start;
+ u8 *data = kzalloc(len, GFP_KERNEL);
+ int ret;
+
+ if (!data)
+ return -ENOMEM;
+
+ ret = mcp25xxfd_cmd_write_regs(cpriv->priv->spi,
+ start, (u32 *)data, len);
+
+ kfree(data);
+
+ return ret;
+}
+
+static int mcp25xxfd_can_fifo_clear(struct mcp25xxfd_can_priv *cpriv)
+{
+ int ret;
+
+ memset(&cpriv->fifos.info, 0, sizeof(cpriv->fifos.info));
+ memset(&cpriv->fifos.tx, 0, sizeof(cpriv->fifos.tx));
+ memset(&cpriv->fifos.rx, 0, sizeof(cpriv->fifos.rx));
+
+ /* clear FIFO config */
+ ret = mcp25xxfd_can_fifo_clear_regs(cpriv, MCP25XXFD_CAN_FIFOCON(1),
+ MCP25XXFD_CAN_FIFOCON(32));
+ if (ret)
+ return ret;
+
+ /* clear the filter mask - match any frame with every filter */
+ return mcp25xxfd_can_fifo_clear_regs(cpriv, MCP25XXFD_CAN_FLTCON(0),
+ MCP25XXFD_CAN_FLTCON(32));
+}
+
+int mcp25xxfd_can_fifo_setup(struct mcp25xxfd_can_priv *cpriv)
+{
+ int ret;
+
+ /* clear fifo config */
+ ret = mcp25xxfd_can_fifo_clear(cpriv);
+ if (ret)
+ return ret;
+
+ /* compute fifos counts */
+ ret = mcp25xxfd_can_fifo_compute(cpriv);
+ if (ret)
+ return ret;
+
+ /* configure TEF */
+ if (cpriv->fifos.tef.count)
+ cpriv->regs.tefcon =
+ MCP25XXFD_CAN_TEFCON_FRESET |
+ MCP25XXFD_CAN_TEFCON_TEFNEIE |
+ MCP25XXFD_CAN_TEFCON_TEFTSEN |
+ ((cpriv->fifos.tef.count - 1) <<
+ MCP25XXFD_CAN_TEFCON_FSIZE_SHIFT);
+ else
+ cpriv->regs.tefcon = 0;
+ ret = mcp25xxfd_cmd_write(cpriv->priv->spi, MCP25XXFD_CAN_TEFCON,
+ cpriv->regs.tefcon);
+ if (ret)
+ return ret;
+
+ /* TXQueue disabled */
+ ret = mcp25xxfd_cmd_write(cpriv->priv->spi, MCP25XXFD_CAN_TXQCON, 0);
+ if (ret)
+ return ret;
+
+ /* configure FIFOS themselves */
+ ret = mcp25xxfd_can_fifo_setup_tx(cpriv);
+ if (ret)
+ return ret;
+ ret = mcp25xxfd_can_fifo_setup_rx(cpriv);
+ if (ret)
+ return ret;
+ ret = mcp25xxfd_can_fifo_setup_rxfilter(cpriv);
+ if (ret)
+ return ret;
+
+ /* get fifo addresses */
+ ret = mcp25xxfd_can_fifo_get_address(cpriv);
+ if (ret)
+ return ret;
+
+ /* setup tx_fifo_queue */
+ ret = mcp25xxfd_can_tx_queue_alloc(cpriv);
+ if (ret)
+ return ret;
+
+ /* add the can info to debugfs */
+ mcp25xxfd_can_debugfs_setup(cpriv);
+
+ return 0;
+}
+
+void mcp25xxfd_can_fifo_release(struct mcp25xxfd_can_priv *cpriv)
+{
+ mcp25xxfd_can_tx_queue_free(cpriv);
+ mcp25xxfd_can_fifo_clear(cpriv);
+ mcp25xxfd_can_debugfs_remove(cpriv);
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.h
new file mode 100644
index 000000000000..ed2daa05220a
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_fifo.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_FIFO_H
+#define __MCP25XXFD_CAN_FIFO_H
+
+#include "mcp25xxfd_can_priv.h"
+
+int mcp25xxfd_can_fifo_setup(struct mcp25xxfd_can_priv *cpriv);
+void mcp25xxfd_can_fifo_release(struct mcp25xxfd_can_priv *cpriv);
+
+#endif /* __MCP25XXFD_CAN_FIFO_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_id.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_id.h
new file mode 100644
index 000000000000..00a6c6639bd5
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_id.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_IF_H
+#define __MCP25XXFD_CAN_IF_H
+
+#include <uapi/linux/can.h>
+
+#include "mcp25xxfd_can_id.h"
+#include "mcp25xxfd_regs.h"
+
+/* ideally these would be defined in uapi/linux/can.h */
+#define MCP25XXFD_CAN_EFF_SID_SHIFT (CAN_EFF_ID_BITS - CAN_SFF_ID_BITS)
+#define MCP25XXFD_CAN_EFF_SID_BITS CAN_SFF_ID_BITS
+#define MCP25XXFD_CAN_EFF_SID_MASK \
+ GENMASK(MCP25XXFD_CAN_EFF_SID_SHIFT + MCP25XXFD_CAN_EFF_SID_BITS - 1, \
+ MCP25XXFD_CAN_EFF_SID_SHIFT)
+#define MCP25XXFD_CAN_EFF_EID_SHIFT 0
+#define MCP25XXFD_CAN_EFF_EID_BITS MCP25XXFD_CAN_EFF_SID_SHIFT
+#define MCP25XXFD_CAN_EFF_EID_MASK \
+ GENMASK(MCP25XXFD_CAN_EFF_EID_SHIFT + MCP25XXFD_CAN_EFF_EID_BITS - 1, \
+ MCP25XXFD_CAN_EFF_EID_SHIFT)
+
+static inline
+void mcp25xxfd_can_id_from_mcp25xxfd(u32 mcp_id, u32 mcp_flags, u32 *can_id)
+{
+ u32 sid = (mcp_id & MCP25XXFD_CAN_OBJ_ID_SID_MASK) >>
+ MCP25XXFD_CAN_OBJ_ID_SID_SHIFT;
+ u32 eid = (mcp_id & MCP25XXFD_CAN_OBJ_ID_EID_MASK) >>
+ MCP25XXFD_CAN_OBJ_ID_EID_SHIFT;
+
+ /* select normal or extended ids */
+ if (mcp_flags & MCP25XXFD_CAN_OBJ_FLAGS_IDE) {
+ *can_id = (eid << MCP25XXFD_CAN_EFF_EID_SHIFT) |
+ (sid << MCP25XXFD_CAN_EFF_SID_SHIFT) |
+ CAN_EFF_FLAG;
+ } else {
+ *can_id = sid << MCP25XXFD_CAN_EFF_EID_SHIFT;
+ }
+ /* handle rtr */
+ *can_id |= (mcp_flags & MCP25XXFD_CAN_OBJ_FLAGS_RTR) ? CAN_RTR_FLAG : 0;
+}
+
+static inline
+void mcp25xxfd_can_id_to_mcp25xxfd(u32 can_id, u32 *id, u32 *flags)
+{
+ /* depending on can_id flag compute extended or standard ids */
+ if (can_id & CAN_EFF_FLAG) {
+ int sid = (can_id & MCP25XXFD_CAN_EFF_SID_MASK) >>
+ MCP25XXFD_CAN_EFF_SID_SHIFT;
+ int eid = (can_id & MCP25XXFD_CAN_EFF_EID_MASK) >>
+ MCP25XXFD_CAN_EFF_EID_SHIFT;
+ *id = (eid << MCP25XXFD_CAN_OBJ_ID_EID_SHIFT) |
+ (sid << MCP25XXFD_CAN_OBJ_ID_SID_SHIFT);
+ *flags = MCP25XXFD_CAN_OBJ_FLAGS_IDE;
+ } else {
+ *id = can_id & CAN_SFF_MASK;
+ *flags = 0;
+ }
+
+ /* Handle RTR */
+ *flags |= (can_id & CAN_RTR_FLAG) ? MCP25XXFD_CAN_OBJ_FLAGS_RTR : 0;
+}
+
+#endif /* __MCP25XXFD_CAN_IF_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.c
new file mode 100644
index 000000000000..9de947da3abc
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_can_debugfs.h"
+#include "mcp25xxfd_can_int.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_can_rx.h"
+#include "mcp25xxfd_can_tx.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_ecc.h"
+#include "mcp25xxfd_int.h"
+#include "mcp25xxfd_regs.h"
+
+static unsigned int reschedule_int_thread_after = 4;
+module_param(reschedule_int_thread_after, uint, 0664);
+MODULE_PARM_DESC(reschedule_int_thread_after,
+ "Reschedule the interrupt thread after this many loops\n");
+
+static void mcp25xxfd_can_int_send_error_skb(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct net_device *net = cpriv->can.dev;
+ struct sk_buff *skb;
+ struct can_frame *frame;
+
+ /* allocate error frame */
+ skb = alloc_can_err_skb(net, &frame);
+ if (!skb) {
+ netdev_err(net, "cannot allocate error skb\n");
+ return;
+ }
+
+ /* setup can error frame data */
+ frame->can_id |= cpriv->error_frame.id;
+ memcpy(frame->data, cpriv->error_frame.data, sizeof(frame->data));
+
+ /* and submit it */
+ netif_rx(skb);
+}
+
+static int mcp25xxfd_can_int_compare_obj_ts(const void *a, const void *b)
+{
+ s32 ats = ((struct mcp25xxfd_obj_ts *)a)->ts;
+ s32 bts = ((struct mcp25xxfd_obj_ts *)b)->ts;
+
+ if (ats < bts)
+ return -1;
+ if (ats > bts)
+ return 1;
+ return 0;
+}
+
+static int mcp25xxfd_can_int_submit_frames(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct mcp25xxfd_obj_ts *queue = cpriv->fifos.submit_queue;
+ int count = cpriv->fifos.submit_queue_count;
+ int i, fifo;
+ int ret;
+
+ /* skip processing if the queue count is 0 */
+ if (count == 0)
+ goto out;
+
+ /* sort the fifos (rx and tx - actually TEF) by receive timestamp */
+ sort(queue, count, sizeof(*queue),
+ mcp25xxfd_can_int_compare_obj_ts, NULL);
+
+ /* now submit the fifos */
+ for (i = 0; i < count; i++) {
+ fifo = queue[i].fifo;
+ ret = (queue[i].is_rx) ?
+ mcp25xxfd_can_rx_submit_frame(cpriv, fifo) :
+ mcp25xxfd_can_tx_submit_frame(cpriv, fifo);
+ if (ret)
+ return ret;
+ }
+
+ /* if we have received or transmitted something
+ * and the IVMIE is disabled, then enable it
+ * this is mostly to avoid unnecessary interrupts during a
+ * disconnected CAN BUS
+ */
+ if (!(cpriv->status.intf | MCP25XXFD_CAN_INT_IVMIE)) {
+ cpriv->status.intf |= MCP25XXFD_CAN_INT_IVMIE;
+ ret = mcp25xxfd_cmd_write_mask(cpriv->priv->spi,
+ MCP25XXFD_CAN_INT,
+ cpriv->status.intf,
+ MCP25XXFD_CAN_INT_IVMIE);
+ if (ret)
+ return ret;
+ }
+
+out:
+ /* enable tx_queue if necessary */
+ mcp25xxfd_can_tx_queue_restart(cpriv);
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_clear_int_flags(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 clearable_irq_active = cpriv->status.intf &
+ MCP25XXFD_CAN_INT_IF_CLEAR_MASK;
+ u32 clear_irq = cpriv->status.intf & (~MCP25XXFD_CAN_INT_IF_CLEAR_MASK);
+
+ /* if no clearable flags are set then skip the whole transfer */
+ if (!clearable_irq_active)
+ return 0;
+
+ return mcp25xxfd_cmd_write_mask(cpriv->priv->spi, MCP25XXFD_CAN_INT,
+ clear_irq, clearable_irq_active);
+}
+
+static
+int mcp25xxfd_can_int_handle_serrif_txmab(struct mcp25xxfd_can_priv *cpriv)
+{
+ int mode = mcp25xxfd_can_targetmode(cpriv);
+
+ cpriv->can.dev->stats.tx_fifo_errors++;
+ cpriv->can.dev->stats.tx_errors++;
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_serr_tx_count);
+
+ /* data7 contains custom mcp25xxfd error flags */
+ cpriv->error_frame.data[7] |= MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_SERR_TX;
+
+ /* and switch back into the correct mode */
+ return mcp25xxfd_can_switch_mode_no_wait(cpriv->priv,
+ &cpriv->regs.con, mode);
+}
+
+static
+int mcp25xxfd_can_int_handle_serrif_rxmab(struct mcp25xxfd_can_priv *cpriv)
+{
+ cpriv->can.dev->stats.rx_dropped++;
+ cpriv->can.dev->stats.rx_errors++;
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_serr_rx_count);
+
+ /* data7 contains custom mcp25xxfd error flags */
+ cpriv->error_frame.data[7] |= MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_SERR_RX;
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_handle_serrif(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_SERRIF))
+ return 0;
+
+ /* increment statistics counter now */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_serr_count);
+
+ /* interrupt flags have been cleared already */
+
+ /* Errors here are:
+ * * Bus Bandwidth Error: when a RX Message Assembly Buffer
+ * is still full when the next message has already arrived
+ * the recived message shall be ignored
+ * * TX MAB Underflow: when a TX Message is invalid
+ * due to ECC errors or TXMAB underflow
+ * in this situatioon the system will transition to
+ * Restricted or Listen Only mode
+ */
+
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_UNSPEC;
+
+ /* a mode change + invalid message would indicate
+ * TX MAB Underflow
+ */
+ if ((cpriv->status.intf & MCP25XXFD_CAN_INT_MODIF) &&
+ (cpriv->status.intf & MCP25XXFD_CAN_INT_IVMIF)) {
+ return mcp25xxfd_can_int_handle_serrif_txmab(cpriv);
+ }
+
+ /* for RX there is only the RXIF an indicator
+ * - surprizingly RX-MAB does not change mode or anything
+ */
+ if (cpriv->status.intf & MCP25XXFD_CAN_INT_RXIF)
+ return mcp25xxfd_can_int_handle_serrif_rxmab(cpriv);
+
+ /* the final case */
+ dev_warn_ratelimited(&cpriv->priv->spi->dev,
+ "unidentified system interrupt - intf = %08x\n",
+ cpriv->status.intf);
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_handle_modif(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct spi_device *spi = cpriv->priv->spi;
+ int mode;
+ int ret;
+
+ /* Note that this irq does not get triggered in all situations
+ * for example SERRIF will move to RESTICTED or LISTENONLY
+ * but MODIF will not be raised!
+ */
+
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_MODIF))
+ return 0;
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_mod_count);
+
+ /* get the current mode */
+ ret = mcp25xxfd_can_get_mode(cpriv->priv, &mode);
+ if (ret < 0)
+ return ret;
+ mode = ret;
+
+ /* switches to the same mode as before are ignored
+ * - this typically happens if the driver is shortly
+ * switching to a different mode and then returning to the
+ * original mode
+ */
+ if (mode == cpriv->mode)
+ return 0;
+
+ /* if we are restricted, then return to "normal" mode */
+ if (mode == MCP25XXFD_CAN_CON_MODE_RESTRICTED) {
+ cpriv->mode = mode;
+ mode = mcp25xxfd_can_targetmode(cpriv);
+ return mcp25xxfd_can_switch_mode_no_wait(cpriv->priv,
+ &cpriv->regs.con,
+ mode);
+ }
+
+ /* the controller itself will transition to sleep, so we ignore it */
+ if (mode == MCP25XXFD_CAN_CON_MODE_SLEEP) {
+ cpriv->mode = mode;
+ return 0;
+ }
+
+ /* these we need to handle correctly, so warn and give context */
+ dev_warn(&spi->dev,
+ "Controller unexpectedly switched from mode %u to %u\n",
+ cpriv->mode, mode);
+
+ /* assign the mode as current */
+ cpriv->mode = mode;
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_handle_eccif(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_ECCIF))
+ return 0;
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_ecc_count);
+
+ /* and prepare ERROR FRAME */
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_UNSPEC;
+ /* data7 contains custom mcp25xxfd error flags */
+ cpriv->error_frame.data[7] |= MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_ECC;
+
+ /* delegate to interrupt cleaning */
+ return mcp25xxfd_ecc_clear_int(cpriv->priv);
+}
+
+static void mcp25xxfd_can_int_handle_ivmif_tx(struct mcp25xxfd_can_priv *cpriv,
+ u32 *mask)
+{
+ /* check if it is really a known tx error */
+ if ((cpriv->bus.bdiag[1] &
+ (MCP25XXFD_CAN_BDIAG1_DBIT1ERR |
+ MCP25XXFD_CAN_BDIAG1_DBIT0ERR |
+ MCP25XXFD_CAN_BDIAG1_NACKERR |
+ MCP25XXFD_CAN_BDIAG1_NBIT1ERR |
+ MCP25XXFD_CAN_BDIAG1_NBIT0ERR |
+ MCP25XXFD_CAN_BDIAG1_TXBOERR
+ )) == 0)
+ return;
+
+ /* mark it as a protocol error */
+ cpriv->error_frame.id |= CAN_ERR_PROT;
+
+ /* and update statistics */
+ cpriv->can.dev->stats.tx_errors++;
+
+ /* and handle all the known cases */
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NACKERR) {
+ /* TX-Frame not acknowledged - connected to CAN-bus? */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NACKERR;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_TX;
+ cpriv->can.dev->stats.tx_aborted_errors++;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NBIT1ERR) {
+ /* TX-Frame CAN-BUS Level is unexpectedly dominant */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NBIT1ERR;
+ cpriv->can.dev->stats.tx_carrier_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_BIT1;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NBIT0ERR) {
+ /* TX-Frame CAN-BUS Level is unexpectedly recessive */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NBIT0ERR;
+ cpriv->can.dev->stats.tx_carrier_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_BIT0;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DBIT1ERR) {
+ /* TX-Frame CAN-BUS Level is unexpectedly dominant
+ * during data phase
+ */
+ *mask |= MCP25XXFD_CAN_BDIAG1_DBIT1ERR;
+ cpriv->can.dev->stats.tx_carrier_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_BIT1;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_TXBOERR) {
+ *mask |= MCP25XXFD_CAN_BDIAG1_TXBOERR;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DBIT0ERR) {
+ /* TX-Frame CAN-BUS Level is unexpectedly recessive
+ * during data phase
+ */
+ *mask |= MCP25XXFD_CAN_BDIAG1_DBIT0ERR;
+ cpriv->can.dev->stats.tx_carrier_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_BIT0;
+ }
+}
+
+static void mcp25xxfd_can_int_handle_ivmif_rx(struct mcp25xxfd_can_priv *cpriv,
+ u32 *mask)
+{
+ /* check if it is really a known tx error */
+ if ((cpriv->bus.bdiag[1] &
+ (MCP25XXFD_CAN_BDIAG1_DCRCERR |
+ MCP25XXFD_CAN_BDIAG1_DSTUFERR |
+ MCP25XXFD_CAN_BDIAG1_DFORMERR |
+ MCP25XXFD_CAN_BDIAG1_NCRCERR |
+ MCP25XXFD_CAN_BDIAG1_NSTUFERR |
+ MCP25XXFD_CAN_BDIAG1_NFORMERR |
+ MCP25XXFD_CAN_BDIAG1_DLCMM
+ )) == 0)
+ return;
+
+ /* mark it as a protocol error */
+ cpriv->error_frame.id |= CAN_ERR_PROT;
+
+ /* and update statistics */
+ cpriv->can.dev->stats.rx_errors++;
+
+ /* handle the cases */
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DCRCERR) {
+ /* RX-Frame with bad CRC during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_DCRCERR;
+ cpriv->can.dev->stats.rx_crc_errors++;
+ cpriv->error_frame.data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DSTUFERR) {
+ /* RX-Frame with bad stuffing during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_DSTUFERR;
+ cpriv->can.dev->stats.rx_frame_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_STUFF;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DFORMERR) {
+ /* RX-Frame with bad format during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_DFORMERR;
+ cpriv->can.dev->stats.rx_frame_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_FORM;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NCRCERR) {
+ /* RX-Frame with bad CRC during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NCRCERR;
+ cpriv->can.dev->stats.rx_crc_errors++;
+ cpriv->error_frame.data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NSTUFERR) {
+ /* RX-Frame with bad stuffing during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NSTUFERR;
+ cpriv->can.dev->stats.rx_frame_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_STUFF;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_NFORMERR) {
+ /* RX-Frame with bad format during data phase */
+ *mask |= MCP25XXFD_CAN_BDIAG1_NFORMERR;
+ cpriv->can.dev->stats.rx_frame_errors++;
+ cpriv->error_frame.data[2] |= CAN_ERR_PROT_FORM;
+ }
+ if (cpriv->bus.bdiag[1] & MCP25XXFD_CAN_BDIAG1_DLCMM) {
+ *mask |= MCP25XXFD_CAN_BDIAG1_DLCMM;
+ cpriv->can.dev->stats.rx_frame_errors++;
+ }
+}
+
+static int mcp25xxfd_can_int_handle_ivmif(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct spi_device *spi = cpriv->priv->spi;
+ u32 mask, bdiag1;
+ int ret;
+
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_IVMIF))
+ return 0;
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_ivm_count);
+
+ /* if we have a systemerror as well,
+ * then ignore it as they correlate
+ */
+ if (cpriv->status.intf & MCP25XXFD_CAN_INT_SERRIF)
+ return 0;
+
+ /* read bus diagnostics */
+ ret = mcp25xxfd_cmd_read_regs(spi, MCP25XXFD_CAN_BDIAG0,
+ cpriv->bus.bdiag,
+ sizeof(cpriv->bus.bdiag));
+ if (ret)
+ return ret;
+
+ /* clear the masks of bits to clear */
+ mask = 0;
+
+ /* check rx and tx errors */
+ mcp25xxfd_can_int_handle_ivmif_tx(cpriv, &mask);
+ mcp25xxfd_can_int_handle_ivmif_rx(cpriv, &mask);
+
+ /* clear flags if we have bits masked */
+ if (!mask) {
+ /* the unsupported case, where we are not
+ * clearing any registers
+ */
+ dev_warn_once(&spi->dev,
+ "found IVMIF situation not supported by driver - bdiag = [0x%08x, 0x%08x]",
+ cpriv->bus.bdiag[0], cpriv->bus.bdiag[1]);
+ } else {
+ /* clear the bits in bdiag1 */
+ bdiag1 = cpriv->bus.bdiag[1] & (~mask);
+ /* and write it */
+ ret = mcp25xxfd_cmd_write_mask(spi, MCP25XXFD_CAN_BDIAG1, bdiag1, mask);
+ if (ret)
+ return ret;
+ }
+
+
+ /* and clear the interrupt flag until we have received or transmited */
+ cpriv->status.intf &= ~(MCP25XXFD_CAN_INT_IVMIE);
+ return mcp25xxfd_cmd_write_mask(spi, MCP25XXFD_CAN_INT,
+ cpriv->status.intf,
+ MCP25XXFD_CAN_INT_IVMIE);
+}
+
+static int mcp25xxfd_can_int_handle_cerrif(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_CERRIF))
+ return 0;
+
+ /* this interrupt exists primarilly to counter possible
+ * bus off situations more detailed information
+ * can be found and controlled in the TREC register
+ */
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_cerr_count);
+
+ netdev_warn(cpriv->can.dev, "CAN Bus error experienced");
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_error_counters(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (cpriv->status.trec & MCP25XXFD_CAN_TREC_TXWARN) {
+ cpriv->bus.new_state = CAN_STATE_ERROR_WARNING;
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ }
+ if (cpriv->status.trec & MCP25XXFD_CAN_TREC_RXWARN) {
+ cpriv->bus.new_state = CAN_STATE_ERROR_WARNING;
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ }
+ if (cpriv->status.trec & MCP25XXFD_CAN_TREC_TXBP) {
+ cpriv->bus.new_state = CAN_STATE_ERROR_PASSIVE;
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+ }
+ if (cpriv->status.trec & MCP25XXFD_CAN_TREC_RXBP) {
+ cpriv->bus.new_state = CAN_STATE_ERROR_PASSIVE;
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ if (cpriv->status.trec & MCP25XXFD_CAN_TREC_TXBO) {
+ cpriv->bus.new_state = CAN_STATE_BUS_OFF;
+ cpriv->error_frame.id |= CAN_ERR_BUSOFF;
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_error_handling(struct mcp25xxfd_can_priv *cpriv)
+{
+ /* based on the last state state check the new state */
+ switch (cpriv->can.state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ if (cpriv->bus.new_state >= CAN_STATE_ERROR_WARNING &&
+ cpriv->bus.new_state <= CAN_STATE_BUS_OFF)
+ cpriv->can.can_stats.error_warning++;
+ /* fallthrough */
+ case CAN_STATE_ERROR_WARNING:
+ if (cpriv->bus.new_state >= CAN_STATE_ERROR_PASSIVE &&
+ cpriv->bus.new_state <= CAN_STATE_BUS_OFF)
+ cpriv->can.can_stats.error_passive++;
+ break;
+ default:
+ break;
+ }
+ cpriv->can.state = cpriv->bus.new_state;
+
+ /* and send error packet */
+ if (cpriv->error_frame.id)
+ mcp25xxfd_can_int_send_error_skb(cpriv);
+
+ /* handle BUS OFF */
+ if (cpriv->can.state == CAN_STATE_BUS_OFF) {
+ if (cpriv->can.restart_ms == 0) {
+ cpriv->can.can_stats.bus_off++;
+ can_bus_off(cpriv->can.dev);
+ }
+ } else {
+ /* restart the tx queue if needed */
+ mcp25xxfd_can_tx_queue_restart(cpriv);
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_int_handle_status(struct mcp25xxfd_can_priv *cpriv)
+{
+ char *errfunc;
+ int ret;
+
+#define HANDLE_ERROR(name) \
+ do { \
+ if (ret) { \
+ errfunc = name; \
+ goto err; \
+ } \
+ } while (0)
+
+ /* clear all the interrupts asap - we have them on file allready */
+ ret = mcp25xxfd_can_int_clear_int_flags(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_clear_int_flags");
+
+ /* set up new state and error frame for this loop */
+ cpriv->bus.new_state = cpriv->bus.state;
+ memset(&cpriv->error_frame, 0, sizeof(cpriv->error_frame));
+
+ /* setup the process queue by clearing the counter */
+ cpriv->fifos.submit_queue_count = 0;
+
+ /* handle interrupts */
+
+ /* system error interrupt needs to get handled first
+ * to get us out of restricted mode
+ */
+ ret = mcp25xxfd_can_int_handle_serrif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_handle_serrif");
+
+ /* mode change interrupt */
+ ret = mcp25xxfd_can_int_handle_modif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_handle_modif");
+
+ /* handle the rx */
+ ret = mcp25xxfd_can_rx_handle_int_rxif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_rx_handle_int_rxif");
+
+ /* handle aborted TX FIFOs */
+ ret = mcp25xxfd_can_tx_handle_int_txatif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_tx_handle_int_txatif");
+
+ /* handle the TEF */
+ ret = mcp25xxfd_can_tx_handle_int_tefif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_rx_handle_int_tefif");
+
+ /* handle error interrupt flags */
+ ret = mcp25xxfd_can_rx_handle_int_rxovif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_rx_handle_int_rxovif");
+
+ /* sram ECC error interrupt */
+ ret = mcp25xxfd_can_int_handle_eccif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_handle_eccif");
+
+ /* message format interrupt */
+ ret = mcp25xxfd_can_int_handle_ivmif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_handle_ivmif");
+
+ /* handle bus errors in more detail */
+ ret = mcp25xxfd_can_int_handle_cerrif(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_handle_cerrif");
+
+ /* error counter handling */
+ ret = mcp25xxfd_can_int_error_counters(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_error_counters");
+
+ /* error counter handling */
+ ret = mcp25xxfd_can_int_error_handling(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_error_handling");
+
+ /* and submit can frames to network stack */
+ ret = mcp25xxfd_can_int_submit_frames(cpriv);
+ HANDLE_ERROR("mcp25xxfd_can_int_submit_frames");
+
+ return 0;
+err:
+ netdev_err(cpriv->can.dev, "%s returned with error code %i\n",
+ errfunc, ret);
+ return ret;
+}
+
+#undef HANDLE_ERROR
+
+irqreturn_t mcp25xxfd_can_int(int irq, void *dev_id)
+{
+ struct mcp25xxfd_can_priv *cpriv = dev_id;
+ int loops, ret;
+
+ /* count interrupt calls */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, irq_calls);
+
+ /* loop forever unless we need to exit */
+ for (loops = 1; true; loops++) {
+ /* count irq loops */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, irq_loops);
+
+ /* read interrupt status flags in bulk */
+ ret = mcp25xxfd_cmd_read_regs(cpriv->priv->spi,
+ MCP25XXFD_CAN_INT,
+ &cpriv->status.intf,
+ sizeof(cpriv->status));
+ switch (ret) {
+ case 0: /* no errors, so process */
+ break;
+ case -EILSEQ: /* a crc error, so run the loop again */
+ continue;
+ default: /* all other error cases */
+ netdev_err(cpriv->can.dev,
+ "reading can registers returned with error code %i\n",
+ ret);
+ goto fail;
+ }
+
+ /* only act if the IE mask configured has active IF bits
+ * otherwise the Interrupt line should be deasserted already
+ * so we can exit the loop
+ */
+ if (((cpriv->status.intf >> MCP25XXFD_CAN_INT_IE_SHIFT) &
+ cpriv->status.intf) == 0)
+ break;
+
+ /* handle the interrupts for real */
+ ret = mcp25xxfd_can_int_handle_status(cpriv);
+ switch (ret) {
+ case 0: /* no errors, so process */
+ case -EILSEQ: /* a crc error, so run the loop again */
+ break;
+ default: /* all other error cases */
+ goto fail;
+ }
+
+ /* allow voluntarily rescheduling every so often to avoid
+ * long CS lows at the end of a transfer on low power CPUs
+ * avoiding SERR happening
+ */
+ if (loops % reschedule_int_thread_after == 0) {
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv,
+ irq_thread_rescheduled);
+ cond_resched();
+ }
+ }
+
+ return IRQ_HANDLED;
+
+fail:
+ netdev_err(cpriv->can.dev,
+ "experienced unexpected error %i in interrupt handler - disabling interrupts\n",
+ ret);
+ /* note that if we experienced an spi error,
+ * then this would produce another error
+ */
+ mcp25xxfd_int_enable(cpriv->priv, false);
+
+ /* we could also put the driver in bus-off mode */
+
+ return IRQ_HANDLED;
+}
+
+int mcp25xxfd_can_int_clear(struct mcp25xxfd_priv *priv)
+{
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_CAN_INT, 0,
+ MCP25XXFD_CAN_INT_IF_MASK);
+}
+
+int mcp25xxfd_can_int_enable(struct mcp25xxfd_priv *priv, bool enable)
+{
+ struct mcp25xxfd_can_priv *cpriv = priv->cpriv;
+ const u32 mask = MCP25XXFD_CAN_INT_TEFIE |
+ MCP25XXFD_CAN_INT_RXIE |
+ MCP25XXFD_CAN_INT_MODIE |
+ MCP25XXFD_CAN_INT_SERRIE |
+ MCP25XXFD_CAN_INT_IVMIE |
+ MCP25XXFD_CAN_INT_CERRIE |
+ MCP25XXFD_CAN_INT_RXOVIE |
+ MCP25XXFD_CAN_INT_ECCIE;
+ u32 value = cpriv ? cpriv->status.intf : 0;
+ int ret;
+
+ /* apply mask and */
+ value &= ~(MCP25XXFD_CAN_INT_IE_MASK);
+ if (enable)
+ value |= mask;
+
+ /* and write to int register */
+ ret = mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_CAN_INT,
+ value, mask);
+ if (ret)
+ return ret;
+ if (!cpriv)
+ return 0;
+
+ cpriv->status.intf = value;
+
+ /* enable/disable interrupt handler */
+ if (cpriv->irq.allocated) {
+ if (enable && !cpriv->irq.enabled)
+ enable_irq(cpriv->priv->spi->irq);
+ if (!enable && cpriv->irq.enabled)
+ disable_irq(cpriv->priv->spi->irq);
+ cpriv->irq.enabled = enable;
+ } else {
+ cpriv->irq.enabled = false;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.h
new file mode 100644
index 000000000000..cc2ad992c307
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_int.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_CAN_INT_H
+#define __MCP25XXFD_CAN_INT_H
+
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_can_int_clear(struct mcp25xxfd_priv *priv);
+int mcp25xxfd_can_int_enable(struct mcp25xxfd_priv *priv, bool enable);
+
+irqreturn_t mcp25xxfd_can_int(int irq, void *dev_id);
+
+#endif /* __MCP25XXFD_CAN_INT_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_priv.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_priv.h
new file mode 100644
index 000000000000..8e6705e3d736
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_priv.h
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_PRIV_H
+#define __MCP25XXFD_CAN_PRIV_H
+
+#include <linux/can/dev.h>
+#include <linux/dcache.h>
+
+#include "mcp25xxfd_priv.h"
+
+#define TX_ECHO_SKB_MAX 32
+
+/* information on each fifo type */
+struct mcp25xxfd_fifo {
+ u32 count;
+ u32 start;
+ u32 size;
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ u64 dlc_usage[16];
+ u64 fd_count;
+#endif /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+};
+
+/* used for sorting incoming messages */
+struct mcp25xxfd_obj_ts {
+ s32 ts; /* using signed to handle rollover correctly when sorting */
+ u16 fifo;
+ s16 is_rx;
+};
+
+/* general info on each fifo */
+struct mcp25xxfd_fifo_info {
+ u32 is_rx;
+ u32 offset;
+ u32 priority;
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ u64 use_count;
+#endif /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+};
+
+struct mcp25xxfd_can_priv {
+ /* can_priv has to be the first one to be usable with alloc_candev
+ * which expects struct can_priv to be right at the start of the
+ * priv structure
+ */
+ struct can_priv can;
+ struct mcp25xxfd_priv *priv;
+ struct regulator *transceiver;
+
+ /* the can mode currently active */
+ int mode;
+
+ /* interrupt state */
+ struct {
+ int enabled;
+ int allocated;
+ } irq;
+
+ /* can config registers */
+ struct {
+ u32 con;
+ u32 tdc;
+ u32 tscon;
+ u32 tefcon;
+ u32 nbtcfg;
+ u32 dbtcfg;
+ } regs;
+
+ /* can status registers (mostly) - read in one go
+ * bdiag0 and bdiag1 are optional, but when
+ * berr counters are requested on a regular basis
+ * during high CAN-bus load this would trigger the fact
+ * that spi_sync would get queued for execution in the
+ * spi thread and the spi handler would not get
+ * called inline in the interrupt thread without any
+ * context switches or wakeups...
+ */
+ struct {
+ u32 intf;
+ /* ASSERT(CAN_INT + 4 == CAN_RXIF) */
+ u32 rxif;
+ /* ASSERT(CAN_RXIF + 4 == CAN_TXIF) */
+ u32 txif;
+ /* ASSERT(CAN_TXIF + 4 == CAN_RXOVIF) */
+ u32 rxovif;
+ /* ASSERT(CAN_RXOVIF + 4 == CAN_TXATIF) */
+ u32 txatif;
+ /* ASSERT(CAN_TXATIF + 4 == CAN_TXREQ) */
+ u32 txreq;
+ /* ASSERT(CAN_TXREQ + 4 == CAN_TREC) */
+ u32 trec;
+ } status;
+
+ /* information of fifo setup */
+ struct {
+ /* define payload size and mode */
+ u32 payload_size;
+ u32 payload_mode;
+
+ /* infos on fifo layout */
+
+ /* TEF */
+ struct {
+ u32 count;
+ u32 size;
+ u32 index;
+ } tef;
+
+ /* info on each fifo */
+ struct mcp25xxfd_fifo_info info[32];
+
+ /* extra info on rx/tx fifo groups */
+ struct mcp25xxfd_fifo tx;
+ struct mcp25xxfd_fifo rx;
+
+ /* queue of can frames that need to get submitted
+ * to the network stack during an interrupt loop in one go
+ * (this gets sorted by timestamp before submission
+ * and contains both rx frames as well tx frames that have
+ * gone over the CAN bus successfully
+ */
+ struct mcp25xxfd_obj_ts submit_queue[32];
+ int submit_queue_count;
+
+ /* the tx queue of spi messages */
+ struct mcp25xxfd_tx_spi_message_queue *tx_queue;
+ } fifos;
+
+ /* statistics exposed via debugfs */
+#define MCP25XXFD_CAN_RX_BULK_READ_BINS 8
+
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ struct dentry *debugfs_dir;
+
+ struct {
+ u64 irq_calls;
+ u64 irq_loops;
+ u64 irq_thread_rescheduled;
+
+ u64 int_serr_count;
+ u64 int_serr_rx_count;
+ u64 int_serr_tx_count;
+ u64 int_mod_count;
+ u64 int_rx_count;
+ u64 int_txat_count;
+ u64 int_tef_count;
+ u64 int_rxov_count;
+ u64 int_ecc_count;
+ u64 int_ivm_count;
+ u64 int_cerr_count;
+
+ u64 tx_fd_count;
+ u64 tx_brs_count;
+
+ u64 tef_reads;
+ u64 tef_read_splits;
+
+ u64 rx_reads;
+ u64 rx_reads_prefetched_too_few;
+ u64 rx_reads_prefetched_too_few_bytes;
+ u64 rx_reads_prefetched_too_many;
+ u64 rx_reads_prefetched_too_many_bytes;
+ u64 rx_single_reads;
+ u64 rx_bulk_reads;
+ u64 rx_bulk_read_sizes[MCP25XXFD_CAN_RX_BULK_READ_BINS];
+ } stats;
+#endif /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+
+ /* history of rx-dlc */
+ struct {
+#define MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE 32
+ u8 dlc[MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE];
+ u8 brs[MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE];
+ u8 index;
+ u32 predicted_len;
+ } rx_history;
+
+ /* bus state */
+ struct {
+ u32 state;
+ u32 new_state;
+ u32 bdiag[2];
+ } bus;
+
+ /* can error messages */
+ struct {
+ u32 id;
+ u8 data[8];
+ } error_frame;
+
+ /* a copy of mcp25xxfd-sram in ram */
+ u8 sram[MCP25XXFD_SRAM_SIZE];
+};
+
+#endif /* __MCP25XXFD_CAN_PRIV_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.c
new file mode 100644
index 000000000000..4381dfc55d89
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.c
@@ -0,0 +1,522 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ *
+ * Based on Microchip MCP251x CAN controller driver written by
+ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
+ */
+
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_can_debugfs.h"
+#include "mcp25xxfd_can_id.h"
+#include "mcp25xxfd_can_priv.h"
+#include "mcp25xxfd_can_rx.h"
+
+/* module parameters */
+static unsigned int rx_prefetch_bytes = -1;
+module_param(rx_prefetch_bytes, uint, 0664);
+MODULE_PARM_DESC(rx_prefetch_bytes,
+ "number of bytes to blindly prefetch when reading a rx-fifo");
+
+static struct sk_buff *
+mcp25xxfd_can_rx_submit_normal_frame(struct mcp25xxfd_can_priv *cpriv,
+ u32 id, u32 dlc, u8 **data)
+{
+ struct can_frame *frame;
+ struct sk_buff *skb;
+
+ /* allocate frame */
+ skb = alloc_can_skb(cpriv->can.dev, &frame);
+ if (!skb)
+ return NULL;
+
+ /* set id, dlc and flags */
+ frame->can_id = id;
+ frame->can_dlc = dlc;
+
+ /* and set the pointer to data */
+ *data = frame->data;
+
+ return skb;
+}
+
+/* it is almost identical except for the type of the frame... */
+static struct sk_buff *
+mcp25xxfd_can_rx_submit_fd_frame(struct mcp25xxfd_can_priv *cpriv,
+ u32 id, u32 flags, u32 len, u8 **data)
+{
+ struct canfd_frame *frame;
+ struct sk_buff *skb;
+
+ /* allocate frame */
+ skb = alloc_canfd_skb(cpriv->can.dev, &frame);
+ if (!skb)
+ return NULL;
+
+ /* set id, dlc and flags */
+ frame->can_id = id;
+ frame->len = len;
+ frame->flags |= flags;
+
+ /* and set the pointer to data */
+ *data = frame->data;
+
+ return skb;
+}
+
+int mcp25xxfd_can_rx_submit_frame(struct mcp25xxfd_can_priv *cpriv, int fifo)
+{
+ struct net_device *net = cpriv->can.dev;
+ int addr = cpriv->fifos.info[fifo].offset;
+ struct mcp25xxfd_can_obj_rx *rx =
+ (struct mcp25xxfd_can_obj_rx *)(cpriv->sram + addr);
+ u8 *data = NULL;
+ struct sk_buff *skb;
+ u32 id, dlc, len, flags;
+
+ /* compute the can_id */
+ mcp25xxfd_can_id_from_mcp25xxfd(rx->id, rx->flags, &id);
+
+ /* and dlc */
+ dlc = (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_DLC_MASK) >>
+ MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT;
+ len = can_dlc2len(dlc);
+
+ /* update stats */
+ net->stats.rx_packets++;
+ net->stats.rx_bytes += len;
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.rx.dlc_usage[dlc]);
+ if (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_FDF)
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.rx.fd_count);
+
+ /* add to rx_history */
+ cpriv->rx_history.dlc[cpriv->rx_history.index] = dlc;
+ cpriv->rx_history.brs[cpriv->rx_history.index] =
+ (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_BRS) ? CANFD_BRS : 0;
+ cpriv->rx_history.index++;
+ if (cpriv->rx_history.index >= MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE)
+ cpriv->rx_history.index = 0;
+
+ /* allocate the skb buffer */
+ if (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_FDF) {
+ flags = 0;
+ flags |= (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_BRS) ?
+ CANFD_BRS : 0;
+ flags |= (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_ESI) ?
+ CANFD_ESI : 0;
+ skb = mcp25xxfd_can_rx_submit_fd_frame(cpriv, id, flags,
+ len, &data);
+ } else {
+ skb = mcp25xxfd_can_rx_submit_normal_frame(cpriv, id,
+ len, &data);
+ }
+ if (!skb) {
+ netdev_err(net, "cannot allocate RX skb\n");
+ net->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+
+ /* copy the payload data */
+ memcpy(data, rx->data, len);
+
+ /* and submit the frame */
+ netif_rx_ni(skb);
+
+ return 0;
+}
+
+static int mcp25xxfd_can_rx_read_frame(struct mcp25xxfd_can_priv *cpriv,
+ int fifo, int prefetch_bytes, bool read)
+{
+ struct spi_device *spi = cpriv->priv->spi;
+ struct net_device *net = cpriv->can.dev;
+ int addr = cpriv->fifos.info[fifo].offset;
+ struct mcp25xxfd_can_obj_rx *rx =
+ (struct mcp25xxfd_can_obj_rx *)(cpriv->sram + addr);
+ int dlc;
+ int len, ret;
+
+ /* we read the header plus prefetch_bytes */
+ if (read) {
+ MCP25XXFD_DEBUGFS_INCR(cpriv->stats.rx_single_reads);
+ ret = mcp25xxfd_cmd_readn(spi, MCP25XXFD_SRAM_ADDR(addr),
+ rx, sizeof(*rx) + prefetch_bytes);
+ if (ret)
+ return ret;
+ }
+
+ /* transpose the headers to CPU format */
+ rx->id = le32_to_cpu(*(__le32 *)&rx->id);
+ rx->flags = le32_to_cpu(*(__le32 *)&rx->flags);
+ rx->ts = le32_to_cpu(*(__le32 *)&rx->ts);
+
+ /* compute len */
+ dlc = (rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_DLC_MASK) >>
+ MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT;
+ len = can_dlc2len(min_t(int, dlc, (net->mtu == CANFD_MTU) ? 15 : 8));
+
+ /* read the remaining data for canfd frames */
+ if (read && len > prefetch_bytes) {
+ /* update stats */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv,
+ rx_reads_prefetched_too_few);
+ MCP25XXFD_DEBUGFS_STATS_ADD(cpriv,
+ rx_reads_prefetched_too_few_bytes,
+ len - prefetch_bytes);
+ /* here the extra portion reading data after prefetch */
+ ret = mcp25xxfd_cmd_readn(spi,
+ MCP25XXFD_SRAM_ADDR(addr) +
+ sizeof(*rx) + prefetch_bytes,
+ &rx->data[prefetch_bytes],
+ len - prefetch_bytes);
+ if (ret)
+ return ret;
+ }
+
+ /* update stats */
+ MCP25XXFD_DEBUGFS_INCR(cpriv->stats.rx_reads);
+ if (len < prefetch_bytes) {
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv,
+ rx_reads_prefetched_too_many);
+ MCP25XXFD_DEBUGFS_STATS_ADD(cpriv,
+ rx_reads_prefetched_too_many,
+ prefetch_bytes - len);
+ }
+
+ /* clear the rest of the buffer - just to be safe */
+ memset(rx->data + len, 0, ((net->mtu == CANFD_MTU) ? 64 : 8) - len);
+
+ /* increment the statistics counter */
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.info[fifo].use_count);
+
+ /* add the fifo to the process queues */
+ mcp25xxfd_can_queue_frame(cpriv, fifo, rx->ts, true);
+
+ /* and clear the interrupt flag for that fifo */
+ return mcp25xxfd_cmd_write_mask(spi, MCP25XXFD_CAN_FIFOCON(fifo),
+ MCP25XXFD_CAN_FIFOCON_FRESET,
+ MCP25XXFD_CAN_FIFOCON_FRESET);
+}
+
+static int mcp25xxfd_can_read_rx_frame_bulk(struct mcp25xxfd_can_priv *cpriv,
+ int fstart,
+ int fend)
+{
+ struct net_device *net = cpriv->can.dev;
+ int count = abs(fend - fstart) + 1;
+ int flowest = min_t(int, fstart, fend);
+ int addr = cpriv->fifos.info[flowest].offset;
+ struct mcp25xxfd_can_obj_rx *rx =
+ (struct mcp25xxfd_can_obj_rx *)(cpriv->sram + addr);
+ int len = (sizeof(*rx) + ((net->mtu == CANFD_MTU) ? 64 : 8)) * count;
+ int fifo, i, ret;
+
+ /* update stats */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, rx_bulk_reads);
+ i = min_t(int, MCP25XXFD_CAN_RX_BULK_READ_BINS - 1, count - 1);
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, rx_bulk_read_sizes[i]);
+
+ /* we read the header plus read_min data bytes */
+ ret = mcp25xxfd_cmd_readn(cpriv->priv->spi, MCP25XXFD_SRAM_ADDR(addr),
+ rx, len);
+ if (ret)
+ return ret;
+
+ /* now process all of them - no need to read... */
+ for (fifo = fstart; count > 0; fifo ++, count--) {
+ ret = mcp25xxfd_can_rx_read_frame(cpriv, fifo, 8, false);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* predict dlc size based on historic behaviour */
+static int mcp25xxfd_can_rx_predict_prefetch(struct mcp25xxfd_can_priv *cpriv)
+{
+ int dlc, i, top;
+ u8 histo[16];
+
+ /* if we have a prefetch set then use that one */
+ if (rx_prefetch_bytes != -1)
+ return min_t(int, rx_prefetch_bytes,
+ (cpriv->can.dev->mtu == CANFD_MTU) ? 64 : 8);
+
+ /* memset */
+ memset(histo, 0, sizeof(histo));
+
+ /* for all others compute the histogram */
+ for (i = 0; i < MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE; i++)
+ histo[cpriv->rx_history.dlc[i]]++;
+
+ /* and now find the highest fit */
+ for (i = (cpriv->can.dev->mtu == CANFD_MTU) ? 15 : 8, dlc = 8, top = 0;
+ i >= 0; i--) {
+ if (top < histo[i]) {
+ top = histo[i];
+ dlc = i;
+ }
+ }
+
+ /* compute length from dlc */
+ cpriv->rx_history.predicted_len = can_dlc2len(dlc);
+
+ /* return the predicted length */
+ /* returned value must be word size aligned */
+ return (ALIGN(cpriv->rx_history.predicted_len, 4));
+}
+
+/* at least in can2.0 mode we can read multiple RX-fifos in one go
+ * in case they are ajactent to each other and thus we can reduce
+ * the number of spi messages produced and this improves spi-bus
+ * usage efficiency.
+ * In canFD mode this may also be possible, but would need some
+ * statistics to decide if it is worth reading a full 64 bytes
+ * in one go.
+ * But those statistics can get used to predict how many bytes
+ * to read together with the can header (which is fixed to 8 at
+ * this very moment.
+ *
+ * notes on the rational here:
+ * * Reading just the CAN header info takes:
+ * * bytes read
+ * * 2 bytes command+address
+ * * 12 bytes data (id, flags, timestamp)
+ * * so that is at the very least 112 SCK (= 14 byte * 8 SCK/1 byte)
+ * - on a Raspberry pi 3 for such short requests actually
+ * 126 SCK (=14 byte * 9 SCK/1 byte)
+ * * some SPI framework overhead which is observed to be 5-10 us
+ * on a raspberry pi 3 (time between SCK and stop SCK start)
+ * * with an effective 17.85 MHz SPI clock on a RPI it takes in total:
+ * it takes 12us = 6us + 6us
+ * * now reading 8 bytes of CAN data (can2.0) takes:
+ * * bytes read
+ * * 2 bytes command+address
+ * * 8 bytes data
+ * * so that is at the very least 80 SCK (= 10 byte * 8 SCK/1 byte)
+ * - on a Raspberry pi 3 for such short requests actually
+ * 90 SCK (= 10 byte * 9 SCK/1 byte)
+ * * some SPI framework overhead which is observed to be 5-10 us
+ * on a raspberry pi 3 (time between SCK and stop SCK start)
+ * * with an effective 17.85 MHz SPI clock on a RPI it takes in total:
+ * it takes 11us = 5.0us + 6us
+ * * now reading CAN header plus 8 bytes of CAN data (can2.0) takes:
+ * * bytes read
+ * * 2 bytes command+address
+ * * 20 bytes data
+ * * so that is at the very least 176 SCK (= 22 byte * 8 SCK/1 byte)
+ * - on a Raspberry pi 3 for such short requests actually
+ * 198 SCK (= 22 byte * 9 SCK/1 byte)
+ * * some SPI framework overhead which is observed to be 5-10 us
+ * on a raspberry pi 3 (time between SCK and stop SCK start)
+ * * with an effective 17.85 MHz SPI clock on a RPI it takes in total:
+ * it takes 17.1us = 11.1us + 6us
+ * * this is faster than the 2 individual SPI transfers for header
+ * and data which is in total 23us
+ * * this is even true for the case where we only have a single
+ * data byte (DLC=1) - the time here is 19.5us on a RPI3
+ * * the only time where we are less efficient is for the DLC=0 case.
+ * but the assumption here is that this is a rare case
+ * To put it into perspective here the full table for a RPI3:
+ * LE 2m pr0 pr1 pr2 pr3 pr4 pr5 pr6 pr7 pr8 pr12 pr16 pr20 pr24 pr32 pr48
+ * pr64
+ * 0 7.1 7.1
+ * 1 14.6 7.6 8.1 8.6 9.1 9.6 10.1 10.6 11.1 13.1
+ * 2 15.1 8.1 8.6 9.1 9.6 10.1 10.6 11.1 13.1
+ * 3 15.6 8.6 9.1 9.6 10.1 10.6 11.1 13.1 15.1
+ * 4 16.1 9.1 9.6 10.1 10.6 11.1 13.1 15.1
+ * 5 16.6 9.6 10.1 10.6 11.1 13.1 15.1
+ * 6 17.1 10.1 10.6 11.1 13.1 15.1
+ * 7 17.6 10.6 11.1 13.1 15.1 17.1
+ * 8 18.1 11.1 13.1 15.1 17.1
+ * 12 20.1 13.1 15.1 17.1 19.2
+ * 16 22.1 15.1 17.1 19.2
+ * 20 24.1 17.1 19.2 23.2
+ * 24 26.2 19.2 23.2
+ * 32 30.2 23.2
+ * 48 38.3 31.3
+ * 64 46.3 39.3
+ * (Parameters: SPI Clock=17.8MHz, SCK/byte=9, overhead=6us)
+ * Legend:
+ * LE = length,
+ * 2m = 2 SPI messages (header+data - except for LEN=0, only header)
+ * prX/pX = prefecth length times (only shown when < 2m and Len >= Prefetch)
+ *
+ * The diagonal schows the "optimal" time when the size of the Can frame would
+ * be known ahead of time - i.e if it would be possible to define RX reception
+ * filters based on can DLC values
+ *
+ * So for any Can frame except for LEN=0 the prefetch data solution is
+ * better for prefetch of data=12 for CanFD.
+ *
+ * Here another table showing the optimal prefetch limits for SPI speeds
+ * vs overhead_us at 8 or 9 SCLK/byte
+ *
+ * MHZ 2us@8 2us@9 4us@8 4us@9 6us@8 6us@9 8us@8 8us@9
+ * 10.0 8b*** 8b*** 8b 8b* 12b** 8b* 12b 12b*
+ * 12.5 8b** 8b*** 12b*** 8b 12b 12b* 16b* 16b**
+ * 15.0 8b** 8b** 12b** 12b*** 16b** 12b 20b** 16b
+ * 17.5 8b* 8b* 12b* 12b** 16b 16b** 20b 20b**
+ * 20.0 8b 8b* 16b*** 12b* 20b** 16b 24b* 20b
+ * (a * signifies not a full match, but for any length > count(*))
+ *
+ * So 8 bytes prefetch seems to be a very good tradeoff for can frame
+ * except for DLC/LEN=0 frames.
+ * The question here is mainly: how many frames do we have with DLC=0
+ * vs all others.
+ *
+ * With some statistics of recent CAN frames this may be set dynamically
+ * in the future.
+ *
+ * For this to work efficiently we would also need an estimate on
+ * the SPI framework overhead, which is a function of the spi-bus-driver
+ * implementation details, CPU type and speed as well as system load.
+ * Also the effective SPI-clock speed is needed as well as the
+ * number of spi clock cycles it takes for a single byte to get transferred
+ * The bcm283x SOC for example pauses the SPI clock one cycle after
+ * every byte it sends unless the data is fed to the controller by DMA.
+ * (but for short transfers DMA mapping is very expensive and not worth
+ * the effort. PIO and - in some situations - polling is used instead to
+ * reduce the number of interrupts and the need for thread scheduling as
+ * much as possible)
+ *
+ * This also means that for can2.0 only configured interfaces
+ * reading multiple rx fifos is a realistic option of optimization
+ */
+
+static int mcp25xxfd_can_rx_read_single_frames(struct mcp25xxfd_can_priv *cpriv,
+ int prefetch)
+{
+ int i, f, ret;
+
+ /* loop all frames */
+ for (i = 0, f = cpriv->fifos.rx.start; i < cpriv->fifos.rx.count;
+ i++, f++) {
+ if (cpriv->status.rxif & BIT(f)) {
+ /* read the frame */
+ ret = mcp25xxfd_can_rx_read_frame(cpriv, f,
+ prefetch, true);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_rx_read_bulk_frames(struct mcp25xxfd_can_priv *cpriv)
+{
+ int i, start, end;
+ int ret;
+
+ /* iterate over fifos trying to find fifos next to each other */
+ for (i = 0, start = cpriv->fifos.rx.start, end = start;
+ i < cpriv->fifos.rx.count; i++, end++, start = end) {
+ /* if bit is not set then continue */
+ if (!(cpriv->status.rxif & BIT(start)))
+ continue;
+ /* find the last fifo with a bit set in sequence */
+ for (end = start; cpriv->status.rxif & BIT(end + 1); end++)
+ ;
+ /* and now read those fifos in bulk */
+ ret = mcp25xxfd_can_read_rx_frame_bulk(cpriv, start, end);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_can_rx_read_fd_frames(struct mcp25xxfd_can_priv *cpriv)
+{
+ int i, count_dlc15, count_brs, prefetch;
+
+ /* get a prediction on prefetch */
+ prefetch = mcp25xxfd_can_rx_predict_prefetch(cpriv);
+
+ /* if the prefetch is < 64 then just read single */
+ if (prefetch < 64)
+ return mcp25xxfd_can_rx_read_single_frames(cpriv, prefetch);
+
+ /* check if we have mostly brs frames of those DLC=15 frames */
+ for (i = 0, count_brs = 0, count_dlc15 = 0;
+ i < MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE; i++)
+ if (cpriv->rx_history.dlc[i] == 15) {
+ count_dlc15++;
+ if (cpriv->rx_history.brs[i])
+ count_brs++;
+ }
+
+ /* if we have at least 33% brs frames then run bulk */
+ if (count_brs * 3 >= count_dlc15)
+ return mcp25xxfd_can_rx_read_bulk_frames(cpriv);
+ else
+ return mcp25xxfd_can_rx_read_single_frames(cpriv, prefetch);
+}
+
+static int mcp25xxfd_can_rx_read_frames(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (cpriv->can.dev->mtu == CANFD_MTU)
+ return mcp25xxfd_can_rx_read_fd_frames(cpriv);
+ else
+ return mcp25xxfd_can_rx_read_bulk_frames(cpriv);
+}
+
+int mcp25xxfd_can_rx_handle_int_rxif(struct mcp25xxfd_can_priv *cpriv)
+{
+ if (!cpriv->status.rxif)
+ return 0;
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_rx_count);
+
+ /* read all the fifos */
+ return mcp25xxfd_can_rx_read_frames(cpriv);
+}
+
+int mcp25xxfd_can_rx_handle_int_rxovif(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 mask = MCP25XXFD_CAN_FIFOSTA_RXOVIF;
+ int ret, i, reg;
+
+ if (!cpriv->status.rxovif)
+ return 0;
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_rxov_count);
+
+ /* clear all fifos that have an overflow bit set */
+ for (i = 0; i < 32; i++) {
+ if (cpriv->status.rxovif & BIT(i)) {
+ /* clear fifo status */
+ reg = MCP25XXFD_CAN_FIFOSTA(i);
+ ret = mcp25xxfd_cmd_write_mask(cpriv->priv->spi,
+ reg, 0, mask);
+ if (ret)
+ return ret;
+
+ /* update statistics */
+ cpriv->can.dev->stats.rx_over_errors++;
+ cpriv->can.dev->stats.rx_errors++;
+
+ /* and prepare ERROR FRAME */
+ cpriv->error_frame.id |= CAN_ERR_CRTL;
+ cpriv->error_frame.data[1] |=
+ CAN_ERR_CRTL_RX_OVERFLOW;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.h
new file mode 100644
index 000000000000..71953e2f3615
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_RX_H
+#define __MCP25XXFD_CAN_RX_H
+
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_can_rx_submit_frame(struct mcp25xxfd_can_priv *cpriv, int fifo);
+
+int mcp25xxfd_can_rx_handle_int_rxif(struct mcp25xxfd_can_priv *cpriv);
+int mcp25xxfd_can_rx_handle_int_rxovif(struct mcp25xxfd_can_priv *cpriv);
+
+#endif /* __MCP25XXFD_CAN_RX_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.c
new file mode 100644
index 000000000000..6256989dcdce
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.c
@@ -0,0 +1,716 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ *
+ * Based on Microchip MCP251x CAN controller driver written by
+ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
+ */
+
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_can_id.h"
+#include "mcp25xxfd_can_tx.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_regs.h"
+
+/* mostly bit manipulations to move between stages */
+static struct mcp25xxfd_tx_spi_message *
+mcp25xxfd_can_tx_queue_first_spi_message(struct mcp25xxfd_tx_spi_message_queue *
+ queue, u32 *bitmap)
+{
+ u32 first = ffs(*bitmap);
+
+ if (!first)
+ return NULL;
+
+ return queue->fifo2message[first - 1];
+}
+
+static void mcp25xxfd_can_tx_queue_remove_spi_message(u32 *bitmap, int fifo)
+{
+ *bitmap &= ~BIT(fifo);
+}
+
+static void mcp25xxfd_can_tx_queue_add_spi_message(u32 *bitmap, int fifo)
+{
+ *bitmap |= BIT(fifo);
+}
+
+static void mcp25xxfd_can_tx_queue_move_spi_message(u32 *src, u32 *dest,
+ int fifo)
+{
+ mcp25xxfd_can_tx_queue_remove_spi_message(src, fifo);
+ mcp25xxfd_can_tx_queue_add_spi_message(dest, fifo);
+}
+
+static void mcp25xxfd_can_tx_spi_message_fill_fifo_complete(void *context)
+{
+ struct mcp25xxfd_tx_spi_message *msg = context;
+ struct mcp25xxfd_can_priv *cpriv = msg->cpriv;
+ struct mcp25xxfd_tx_spi_message_queue *q = cpriv->fifos.tx_queue;
+ unsigned long flags;
+
+ /* reset transfer length to without data (DLC = 0) */
+ msg->fill_fifo.xfer.len = sizeof(msg->fill_fifo.data.cmd) +
+ sizeof(msg->fill_fifo.data.header);
+
+ /* we need to hold this lock to protect us from
+ * concurrent access by start_xmit
+ */
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+
+ /* move to in_trigger_fifo_transfer */
+ mcp25xxfd_can_tx_queue_move_spi_message(&q->in_fill_fifo_transfer,
+ &q->in_trigger_fifo_transfer,
+ msg->fifo);
+
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+}
+
+static void mcp25xxfd_can_tx_spi_message_trigger_fifo_complete(void *context)
+{
+ struct mcp25xxfd_tx_spi_message *msg = context;
+ struct mcp25xxfd_can_priv *cpriv = msg->cpriv;
+ struct mcp25xxfd_tx_spi_message_queue *q = cpriv->fifos.tx_queue;
+ unsigned long flags;
+
+ /* we need to hold this lock to protect us from
+ * concurrent access by the interrupt thread
+ */
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+
+ /* move to can_transfer */
+ mcp25xxfd_can_tx_queue_move_spi_message(&q->in_trigger_fifo_transfer,
+ &q->in_can_transfer,
+ msg->fifo);
+
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+}
+
+static
+void mcp25xxfd_can_tx_message_init(struct mcp25xxfd_can_priv *cpriv,
+ struct mcp25xxfd_tx_spi_message *msg,
+ int fifo)
+{
+ const u32 trigger = MCP25XXFD_CAN_FIFOCON_TXREQ |
+ MCP25XXFD_CAN_FIFOCON_UINC;
+ const int first_byte = mcp25xxfd_cmd_first_byte(trigger);
+ u32 addr;
+
+ /* and initialize the structure */
+ msg->cpriv = cpriv;
+ msg->fifo = fifo;
+
+ /* init fill_fifo */
+ spi_message_init(&msg->fill_fifo.msg);
+ msg->fill_fifo.msg.complete =
+ mcp25xxfd_can_tx_spi_message_fill_fifo_complete;
+ msg->fill_fifo.msg.context = msg;
+
+ msg->fill_fifo.xfer.speed_hz = cpriv->priv->spi_use_speed_hz;
+ msg->fill_fifo.xfer.tx_buf = msg->fill_fifo.data.cmd;
+ msg->fill_fifo.xfer.len = sizeof(msg->fill_fifo.data.cmd) +
+ sizeof(msg->fill_fifo.data.header);
+ spi_message_add_tail(&msg->fill_fifo.xfer, &msg->fill_fifo.msg);
+
+ addr = MCP25XXFD_SRAM_ADDR(cpriv->fifos.info[fifo].offset);
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_WRITE, addr,
+ msg->fill_fifo.data.cmd);
+
+ /* init trigger_fifo */
+ spi_message_init(&msg->trigger_fifo.msg);
+ msg->trigger_fifo.msg.complete =
+ mcp25xxfd_can_tx_spi_message_trigger_fifo_complete;
+ msg->trigger_fifo.msg.context = msg;
+
+ msg->trigger_fifo.xfer.speed_hz = cpriv->priv->spi_use_speed_hz;
+ msg->trigger_fifo.xfer.tx_buf = msg->trigger_fifo.data.cmd;
+ msg->trigger_fifo.xfer.len = sizeof(msg->trigger_fifo.data.cmd) +
+ sizeof(msg->trigger_fifo.data.data);
+ spi_message_add_tail(&msg->trigger_fifo.xfer, &msg->trigger_fifo.msg);
+
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_WRITE,
+ MCP25XXFD_CAN_FIFOCON(fifo) + first_byte,
+ msg->trigger_fifo.data.cmd);
+ msg->trigger_fifo.data.data = trigger >> (8 * first_byte);
+
+ /* and add to idle tx transfers */
+ mcp25xxfd_can_tx_queue_add_spi_message(&cpriv->fifos.tx_queue->idle,
+ fifo);
+}
+
+static
+void mcp25xxfd_can_tx_queue_manage_nolock(struct mcp25xxfd_can_priv *cpriv,
+ int state)
+{
+ struct net_device *net = cpriv->can.dev;
+
+ /* skip early */
+ if (state == cpriv->fifos.tx_queue->state)
+ return;
+
+ /* start/stop netif_queue if necessary */
+ switch (cpriv->fifos.tx_queue->state) {
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_RUNABLE:
+ switch (state) {
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_RESTART:
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED:
+ netif_wake_queue(net);
+ cpriv->fifos.tx_queue->state =
+ MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED;
+ break;
+ }
+ break;
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_STOPPED:
+ switch (state) {
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED:
+ netif_wake_queue(net);
+ cpriv->fifos.tx_queue->state = state;
+ break;
+ }
+ break;
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED:
+ switch (state) {
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_RUNABLE:
+ case MCP25XXFD_CAN_TX_QUEUE_STATE_STOPPED:
+ netif_stop_queue(net);
+ cpriv->fifos.tx_queue->state = state;
+ break;
+ }
+ break;
+ default:
+ WARN(true, "Unsupported tx_queue state: %i\n",
+ cpriv->fifos.tx_queue->state);
+ break;
+ }
+}
+
+void mcp25xxfd_can_tx_queue_manage(struct mcp25xxfd_can_priv *cpriv, int state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+
+ mcp25xxfd_can_tx_queue_manage_nolock(cpriv, state);
+
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+}
+
+void mcp25xxfd_can_tx_queue_restart(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 state = MCP25XXFD_CAN_TX_QUEUE_STATE_RESTART;
+ unsigned long flags;
+ u32 mask;
+
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+
+ /* only move if there is nothing pending or idle */
+ mask = cpriv->fifos.tx_queue->idle |
+ cpriv->fifos.tx_queue->in_fill_fifo_transfer |
+ cpriv->fifos.tx_queue->in_trigger_fifo_transfer |
+ cpriv->fifos.tx_queue->in_can_transfer;
+ if (mask)
+ goto out;
+
+ /* move all items from transferred to idle */
+ cpriv->fifos.tx_queue->idle |= cpriv->fifos.tx_queue->transferred;
+ cpriv->fifos.tx_queue->transferred = 0;
+
+ /* and enable queue */
+ mcp25xxfd_can_tx_queue_manage_nolock(cpriv, state);
+out:
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+}
+
+static
+int mcp25xxfd_can_tx_tef_read(struct mcp25xxfd_can_priv *cpriv,
+ int start, int count)
+{
+ u32 tef_offset = start * cpriv->fifos.tef.size;
+ struct mcp25xxfd_can_obj_tef *tef =
+ (struct mcp25xxfd_can_obj_tef *)(cpriv->sram + tef_offset);
+ int last, read, ret;
+
+ /* compute how many we can read in one go */
+ last = start + count;
+ read = (last > cpriv->fifos.tef.count) ?
+ (cpriv->fifos.tef.count - start) :
+ count;
+
+ /* and read it */
+ ret = mcp25xxfd_cmd_read_regs(cpriv->priv->spi,
+ MCP25XXFD_SRAM_ADDR(tef_offset),
+ &tef->id, sizeof(*tef) * read);
+ if (ret)
+ return ret;
+
+ /* and read a second part on wrap */
+ if (read != count) {
+ /* update stats */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tef_read_splits);
+ /* compute the addresses */
+ read = count - read;
+ tef = (struct mcp25xxfd_can_obj_tef *)(cpriv->sram);
+ /* and read again */
+ ret = mcp25xxfd_cmd_read_regs(cpriv->priv->spi,
+ MCP25XXFD_SRAM_ADDR(0),
+ &tef->id,
+ sizeof(*tef) * read);
+ }
+
+ return ret;
+}
+
+static
+int mcp25xxfd_can_tx_handle_int_tefif_fifo(struct mcp25xxfd_can_priv *cpriv,
+ bool read_data)
+{
+ u32 tef_offset = cpriv->fifos.tef.index * cpriv->fifos.tef.size;
+ struct mcp25xxfd_can_obj_tef *tef =
+ (struct mcp25xxfd_can_obj_tef *)(cpriv->sram + tef_offset);
+ int fifo, ret;
+ unsigned long flags;
+
+ /* read the next TEF entry to get the transmit timestamp and fifo */
+ if (read_data) {
+ ret = mcp25xxfd_can_tx_tef_read(cpriv,
+ cpriv->fifos.tef.index, 1);
+ if (ret)
+ return ret;
+ }
+
+ /* get the fifo from tef */
+ fifo = (tef->flags & MCP25XXFD_CAN_OBJ_FLAGS_SEQ_MASK) >>
+ MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT;
+
+ /* check that the fifo is valid */
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+ if ((cpriv->fifos.tx_queue->in_can_transfer & BIT(fifo)) == 0)
+ netdev_err(cpriv->can.dev,
+ "tefif: fifo %i not pending - tef data: id: %08x flags: %08x, ts: %08x - this may be a problem with spi signal quality- try reducing spi-clock speed if this can get reproduced",
+ fifo, tef->id, tef->flags, tef->ts);
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+
+ /* update stats */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tef_reads);
+
+ /* now we can schedule the fifo for echo submission */
+ mcp25xxfd_can_queue_frame(cpriv, fifo, tef->ts, false);
+
+ /* increment the tef index with wraparround */
+ cpriv->fifos.tef.index++;
+ if (cpriv->fifos.tef.index >= cpriv->fifos.tef.count)
+ cpriv->fifos.tef.index = 0;
+
+ /* finally just increment the TEF pointer */
+ return mcp25xxfd_cmd_write_mask(cpriv->priv->spi, MCP25XXFD_CAN_TEFCON,
+ MCP25XXFD_CAN_TEFCON_UINC,
+ MCP25XXFD_CAN_TEFCON_UINC);
+}
+
+/* reading TEF entries can be made even more efficient by reading
+ * multiple TEF entries in one go.
+ * Under the assumption that we have count(TEF) >= count(TX_FIFO)
+ * we can even release TEFs early (before we read them)
+ * (and potentially restarting the transmit-queue early aswell)
+ */
+
+int mcp25xxfd_can_tx_handle_int_tefif(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 tefsta;
+ int ret;
+
+ if (!(cpriv->status.intf & MCP25XXFD_CAN_INT_TEFIF))
+ return 0;
+
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_tef_count);
+
+
+ /* read the TEF status */
+ ret = mcp25xxfd_cmd_read_mask(cpriv->priv->spi, MCP25XXFD_CAN_TEFSTA,
+ &tefsta, MCP25XXFD_CAN_TEFSTA_TEFNEIF);
+ if (ret)
+ return ret;
+
+ /* read the tef in an inefficient loop */
+ while (tefsta & MCP25XXFD_CAN_TEFSTA_TEFNEIF) {
+ /* read one tef */
+ ret = mcp25xxfd_can_tx_handle_int_tefif_fifo(cpriv, true);
+ if (ret)
+ return ret;
+
+ /* read the TEF status */
+ ret = mcp25xxfd_cmd_read_mask(cpriv->priv->spi,
+ MCP25XXFD_CAN_TEFSTA, &tefsta,
+ MCP25XXFD_CAN_TEFSTA_TEFNEIF);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static
+void mcp25xxfd_can_tx_fill_fifo_common(struct mcp25xxfd_can_priv *cpriv,
+ struct mcp25xxfd_tx_spi_message *smsg,
+ struct mcp25xxfd_can_obj_tx *tx,
+ int dlc, u8 *data)
+{
+ int len = can_dlc2len(dlc);
+
+ /* update statistics */
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.tx.dlc_usage[dlc]);
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.info[smsg->fifo].use_count);
+
+ /* add fifo number as seq */
+ tx->flags |= smsg->fifo << MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT;
+
+ /* copy data to tx->data for future reference */
+ memcpy(tx->data, data, len);
+
+ /* transform header to controller format */
+ mcp25xxfd_cmd_convert_from_cpu(&tx->id, sizeof(*tx) / sizeof(u32));
+
+ /* copy header + data to final location - we are not aligned */
+ memcpy(smsg->fill_fifo.data.header, &tx->id, sizeof(*tx) + len);
+
+ /* transfers to sram should be a multiple of 4 and be zero padded */
+ for (; len & 3; len++)
+ *(smsg->fill_fifo.data.header + sizeof(*tx) + len) = 0;
+
+ /* convert it back to CPU format */
+ mcp25xxfd_cmd_convert_to_cpu(&tx->id, sizeof(*tx) / sizeof(u32));
+
+ /* set up size of transfer */
+ smsg->fill_fifo.xfer.len = sizeof(smsg->fill_fifo.data.cmd) +
+ sizeof(smsg->fill_fifo.data.header) + len;
+}
+
+static
+void mcp25xxfd_can_tx_fill_fifo_fd(struct mcp25xxfd_can_priv *cpriv,
+ struct canfd_frame *frame,
+ struct mcp25xxfd_tx_spi_message *smsg,
+ struct mcp25xxfd_can_obj_tx *tx)
+{
+ int dlc = can_len2dlc(frame->len);
+
+ /* update some statistics */
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tx_fd_count);
+
+ /* compute can id */
+ mcp25xxfd_can_id_to_mcp25xxfd(frame->can_id, &tx->id, &tx->flags);
+
+ /* setup flags */
+ tx->flags |= dlc << MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT;
+ tx->flags |= (frame->can_id & CAN_EFF_FLAG) ?
+ MCP25XXFD_CAN_OBJ_FLAGS_IDE : 0;
+ tx->flags |= (frame->can_id & CAN_RTR_FLAG) ?
+ MCP25XXFD_CAN_OBJ_FLAGS_RTR : 0;
+ if (frame->flags & CANFD_BRS) {
+ tx->flags |= MCP25XXFD_CAN_OBJ_FLAGS_BRS;
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tx_brs_count);
+ }
+ tx->flags |= (frame->flags & CANFD_ESI) ?
+ MCP25XXFD_CAN_OBJ_FLAGS_ESI : 0;
+ tx->flags |= MCP25XXFD_CAN_OBJ_FLAGS_FDF;
+
+ /* and do common processing */
+ mcp25xxfd_can_tx_fill_fifo_common(cpriv, smsg, tx, dlc, frame->data);
+}
+
+static
+void mcp25xxfd_can_tx_fill_fifo(struct mcp25xxfd_can_priv *cpriv,
+ struct can_frame *frame,
+ struct mcp25xxfd_tx_spi_message *smsg,
+ struct mcp25xxfd_can_obj_tx *tx)
+{
+ /* set frame to valid dlc */
+ if (frame->can_dlc > 8)
+ frame->can_dlc = 8;
+
+ /* compute can id */
+ mcp25xxfd_can_id_to_mcp25xxfd(frame->can_id, &tx->id, &tx->flags);
+
+ /* setup flags */
+ tx->flags |= frame->can_dlc << MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT;
+ tx->flags |= (frame->can_id & CAN_EFF_FLAG) ?
+ MCP25XXFD_CAN_OBJ_FLAGS_IDE : 0;
+ tx->flags |= (frame->can_id & CAN_RTR_FLAG) ?
+ MCP25XXFD_CAN_OBJ_FLAGS_RTR : 0;
+
+ /* and do common processing */
+ mcp25xxfd_can_tx_fill_fifo_common(cpriv, smsg, tx, frame->can_dlc,
+ frame->data);
+}
+
+static struct mcp25xxfd_tx_spi_message *
+mcp25xxfd_can_tx_queue_get_next_fifo(struct mcp25xxfd_can_priv *cpriv)
+{
+ u32 state = MCP25XXFD_CAN_TX_QUEUE_STATE_RUNABLE;
+ struct mcp25xxfd_tx_spi_message_queue *q = cpriv->fifos.tx_queue;
+ struct mcp25xxfd_tx_spi_message *smsg;
+ unsigned long flags;
+
+ /* we need to hold this lock to protect us against
+ * concurrent modifications of cpriv->fifos.tx_queue->idle
+ * in the interrupt thread
+ */
+ spin_lock_irqsave(&q->lock, flags);
+
+ /* get the first entry from idle */
+ smsg = mcp25xxfd_can_tx_queue_first_spi_message(q, &q->idle);
+ if (!smsg)
+ goto out_busy;
+
+ /* and move the fifo to next stage */
+ mcp25xxfd_can_tx_queue_move_spi_message(&q->idle,
+ &q->in_fill_fifo_transfer,
+ smsg->fifo);
+
+ /* if queue is empty then stop the network queue immediately */
+ if (!q->idle)
+ mcp25xxfd_can_tx_queue_manage_nolock(cpriv, state);
+out_busy:
+ spin_unlock_irqrestore(&q->lock, flags);
+
+ return smsg;
+}
+
+/* submit the can message to the can-bus */
+netdev_tx_t mcp25xxfd_can_tx_start_xmit(struct sk_buff *skb,
+ struct net_device *net)
+{
+ u32 state = MCP25XXFD_CAN_TX_QUEUE_STATE_STOPPED;
+ struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
+ struct mcp25xxfd_priv *priv = cpriv->priv;
+ struct spi_device *spi = priv->spi;
+ struct mcp25xxfd_tx_spi_message *smsg;
+ struct mcp25xxfd_can_obj_tx *tx;
+ int ret;
+
+ /* invalid skb we can ignore */
+ if (can_dropped_invalid_skb(net, skb))
+ return NETDEV_TX_OK;
+
+ /* get the fifo message structure to process now */
+ smsg = mcp25xxfd_can_tx_queue_get_next_fifo(cpriv);
+ if (!smsg)
+ goto out_busy;
+
+ /* compute the fifo in sram */
+ tx = (struct mcp25xxfd_can_obj_tx *)
+ (cpriv->sram + cpriv->fifos.info[smsg->fifo].offset);
+
+ /* fill in message from skb->data depending on can2.0 or canfd */
+ if (can_is_canfd_skb(skb))
+ mcp25xxfd_can_tx_fill_fifo_fd(cpriv,
+ (struct canfd_frame *)skb->data,
+ smsg, tx);
+ else
+ mcp25xxfd_can_tx_fill_fifo(cpriv,
+ (struct can_frame *)skb->data,
+ smsg, tx);
+
+ /* submit the two messages asyncronously
+ * the reason why we separate transfers into two spi_messages is:
+ * * because the spi framework (currently) does add a 10us delay
+ * between 2 spi_transfers in a single spi_message when
+ * change_cs is set - 2 consecutive spi messages show a shorter
+ * cs disable phase increasing bus utilization
+ * (code reduction with a fix in spi core would be aprox.50 lines)
+ * * this allows the interrupt handler to start spi messages earlier
+ * so reducing latencies a bit and to allow for better concurrency
+ * * this separation - in the future - may get used to fill fifos
+ * early and reduce the delay on "rollover"
+ */
+ ret = spi_async(spi, &smsg->fill_fifo.msg);
+ if (ret)
+ goto out_async_failed;
+
+ /* keep it for reference until the message really got transmitted */
+ can_put_echo_skb(skb, net, smsg->fifo);
+
+ ret = spi_async(spi, &smsg->trigger_fifo.msg);
+ if (ret)
+ goto out_async_failed;
+
+ return NETDEV_TX_OK;
+out_async_failed:
+ netdev_err(net, "spi_async submission of fifo %i failed - %i\n",
+ smsg->fifo, ret);
+
+out_busy:
+ /* stop the queue */
+ mcp25xxfd_can_tx_queue_manage_nolock(cpriv, state);
+
+ return NETDEV_TX_BUSY;
+}
+
+/* submit the fifo back to the network stack */
+int mcp25xxfd_can_tx_submit_frame(struct mcp25xxfd_can_priv *cpriv, int fifo)
+{
+ struct mcp25xxfd_tx_spi_message_queue *q = cpriv->fifos.tx_queue;
+ struct mcp25xxfd_can_obj_tx *tx = (struct mcp25xxfd_can_obj_tx *)
+ (cpriv->sram + cpriv->fifos.info[fifo].offset);
+ int dlc = (tx->flags & MCP25XXFD_CAN_OBJ_FLAGS_DLC_MASK) >>
+ MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT;
+ unsigned long flags;
+
+ /* update counters */
+ cpriv->can.dev->stats.tx_packets++;
+ cpriv->can.dev->stats.tx_bytes += can_dlc2len(dlc);
+ MCP25XXFD_DEBUGFS_INCR(cpriv->fifos.tx.dlc_usage[dlc]);
+ if (tx->flags & MCP25XXFD_CAN_OBJ_FLAGS_FDF)
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tx_fd_count);
+ if (tx->flags & MCP25XXFD_CAN_OBJ_FLAGS_BRS)
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, tx_brs_count);
+
+ spin_lock_irqsave(&cpriv->fifos.tx_queue->lock, flags);
+
+ /* release the echo buffer */
+ can_get_echo_skb(cpriv->can.dev, fifo);
+
+ /* move from in_can_transfer to transferred */
+ mcp25xxfd_can_tx_queue_move_spi_message(&q->in_can_transfer,
+ &q->transferred, fifo);
+
+ spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);
+
+ return 0;
+}
+
+/* interrupt handler */
+static
+int mcp25xxfd_can_tx_handle_int_txatif_fifo(struct mcp25xxfd_can_priv *cpriv,
+ int fifo)
+{
+ struct mcp25xxfd_tx_spi_message_queue *q = cpriv->fifos.tx_queue;
+ u32 val;
+ unsigned long flags;
+ int ret;
+
+ /* read fifo status */
+ ret = mcp25xxfd_cmd_read(cpriv->priv->spi,
+ MCP25XXFD_CAN_FIFOSTA(fifo), &val);
+ if (ret)
+ return ret;
+
+ /* clear the relevant interrupt flags */
+ ret = mcp25xxfd_cmd_write_mask(cpriv->priv->spi,
+ MCP25XXFD_CAN_FIFOSTA(fifo), 0,
+ MCP25XXFD_CAN_FIFOSTA_TXABT |
+ MCP25XXFD_CAN_FIFOSTA_TXLARB |
+ MCP25XXFD_CAN_FIFOSTA_TXERR |
+ MCP25XXFD_CAN_FIFOSTA_TXATIF);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&q->lock, flags);
+ /* for specific cases we probably could trigger a retransmit
+ * instead of an abort.
+ */
+
+ /* and we release it from the echo_skb buffer
+ * NOTE: this is one place where packet delivery will not
+ * be ordered, as we do not have any timing information
+ * when this occurred
+ */
+ can_get_echo_skb(cpriv->can.dev, fifo);
+
+ mcp25xxfd_can_tx_queue_move_spi_message(&q->in_can_transfer,
+ &q->transferred, fifo);
+
+ spin_unlock_irqrestore(&q->lock, flags);
+
+ /* but we need to run a bit of cleanup */
+ cpriv->status.txif &= ~BIT(fifo);
+ cpriv->can.dev->stats.tx_aborted_errors++;
+
+ /* handle all the known cases accordingly - ignoring FIFO full */
+ val &= MCP25XXFD_CAN_FIFOSTA_TXABT |
+ MCP25XXFD_CAN_FIFOSTA_TXLARB |
+ MCP25XXFD_CAN_FIFOSTA_TXERR;
+ switch (val) {
+ case MCP25XXFD_CAN_FIFOSTA_TXERR:
+ /* this indicates a possible bus error */
+ break;
+ default:
+ dev_warn_ratelimited(&cpriv->priv->spi->dev,
+ "Unknown TX-Fifo abort condition: %08x - stopping tx-queue\n",
+ val);
+ break;
+ }
+
+ return 0;
+}
+
+int mcp25xxfd_can_tx_handle_int_txatif(struct mcp25xxfd_can_priv *cpriv)
+{
+ int i, f, ret;
+
+ /* if txatif is unset, then there are no
+ * can frames that have been transmitted
+ * and need to get reingested into the network stack
+ */
+ if (!cpriv->status.txatif)
+ return 0;
+ MCP25XXFD_DEBUGFS_STATS_INCR(cpriv, int_txat_count);
+
+ /* process all the fifos with that flag set */
+ for (i = 0, f = cpriv->fifos.tx.start; i < cpriv->fifos.tx.count;
+ i++, f++) {
+ if (cpriv->status.txatif & BIT(f)) {
+ ret = mcp25xxfd_can_tx_handle_int_txatif_fifo(cpriv, f);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int mcp25xxfd_can_tx_queue_alloc(struct mcp25xxfd_can_priv *cpriv)
+{
+ struct mcp25xxfd_tx_spi_message *msg;
+ size_t size = sizeof(struct mcp25xxfd_tx_spi_message_queue) +
+ cpriv->fifos.tx.count * sizeof(*msg);
+ int i, f;
+
+ /* allocate the fifos as an array */
+ cpriv->fifos.tx_queue = kzalloc(size, GFP_KERNEL);
+ if (!cpriv->fifos.tx_queue)
+ return -ENOMEM;
+
+ /* initialize the tx_queue structure */
+ spin_lock_init(&cpriv->fifos.tx_queue->lock);
+
+ /* initialize the individual spi_message structures */
+ for (i = 0, f = cpriv->fifos.tx.start; i < cpriv->fifos.tx.count;
+ i++, f++) {
+ msg = &cpriv->fifos.tx_queue->message[i];
+ cpriv->fifos.tx_queue->fifo2message[f] = msg;
+ mcp25xxfd_can_tx_message_init(cpriv, msg, f);
+ }
+
+ return 0;
+}
+
+void mcp25xxfd_can_tx_queue_free(struct mcp25xxfd_can_priv *cpriv)
+{
+ /* eventually we may need to wait here
+ * for all transfers to have finished
+ */
+
+ kfree(cpriv->fifos.tx_queue);
+ cpriv->fifos.tx_queue = NULL;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.h
new file mode 100644
index 000000000000..1000a80b1ee0
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CAN_TX_H
+#define __MCP25XXFD_CAN_TX_H
+
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_can_priv.h"
+
+/* structure of a spi message that is prepared and can get submitted quickly */
+struct mcp25xxfd_tx_spi_message {
+ /* the network device this is related to */
+ struct mcp25xxfd_can_priv *cpriv;
+ /* the fifo this fills */
+ u32 fifo;
+ /* the xfer to fill in the fifo data */
+ struct {
+ struct spi_message msg;
+ struct spi_transfer xfer;
+ struct {
+ u8 cmd[2];
+ u8 header[sizeof(struct mcp25xxfd_can_obj_tx)];
+ u8 data[64];
+ } data;
+ } fill_fifo;
+ /* the xfer to enable transmission on the can bus */
+ struct {
+ struct spi_message msg;
+ struct spi_transfer xfer;
+ struct {
+ u8 cmd[2];
+ u8 data;
+ } data;
+ } trigger_fifo;
+};
+
+struct mcp25xxfd_tx_spi_message_queue {
+ /* spinlock protecting the bitmaps
+ * as well as state and the skb_echo_* functions
+ */
+ spinlock_t lock;
+ /* bitmap of which fifo is in which stage */
+ u32 idle;
+ u32 in_fill_fifo_transfer;
+ u32 in_trigger_fifo_transfer;
+ u32 in_can_transfer;
+ u32 transferred;
+
+ /* the queue state as seen per controller */
+ int state;
+#define MCP25XXFD_CAN_TX_QUEUE_STATE_STOPPED 0
+#define MCP25XXFD_CAN_TX_QUEUE_STATE_STARTED 1
+#define MCP25XXFD_CAN_TX_QUEUE_STATE_RUNABLE 2
+#define MCP25XXFD_CAN_TX_QUEUE_STATE_RESTART 3
+
+ /* map each fifo to a mcp25xxfd_tx_spi_message */
+ struct mcp25xxfd_tx_spi_message *fifo2message[32];
+
+ /* the individual messages */
+ struct mcp25xxfd_tx_spi_message message[];
+};
+
+int mcp25xxfd_can_tx_submit_frame(struct mcp25xxfd_can_priv *cpriv, int fifo);
+void mcp25xxfd_can_tx_queue_restart(struct mcp25xxfd_can_priv *cpriv);
+
+int mcp25xxfd_can_tx_handle_int_txatif(struct mcp25xxfd_can_priv *cpriv);
+int mcp25xxfd_can_tx_handle_int_tefif(struct mcp25xxfd_can_priv *cpriv);
+
+netdev_tx_t mcp25xxfd_can_tx_start_xmit(struct sk_buff *skb,
+ struct net_device *net);
+
+void mcp25xxfd_can_tx_queue_manage(struct mcp25xxfd_can_priv *cpriv, int state);
+
+int mcp25xxfd_can_tx_queue_alloc(struct mcp25xxfd_can_priv *cpriv);
+void mcp25xxfd_can_tx_queue_free(struct mcp25xxfd_can_priv *cpriv);
+
+#endif /* __MCP25XXFD_CAN_TX_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.c
new file mode 100644
index 000000000000..32b5888df88e
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.c
@@ -0,0 +1,498 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+/* Known hardware issues and workarounds in this driver:
+ *
+ * * There is one situation where the controller will require a full POR
+ * (total power off) to recover from a bad Clock configuration.
+ * This happens when the wrong clock is configured in the device tree
+ * (say 4MHz are configured, while 40MHz is the actual clock frequency
+ * of the HW).
+ * In such a situation the driver tries to enable the PLL, which will
+ * never synchronize and the controller becomes unresponsive to further
+ * spi requests until a full POR.
+ *
+ * Mitigation:
+ * none as of now
+ *
+ * Possible implementation of a mitigation/sanity check:
+ * during initialization:
+ * * try to identify the HW at 1MHz:
+ * on success:
+ * * controller is identified
+ * on failure:
+ * * controller is absent - fail
+ * * force controller clock to run with disabled PLL
+ * * try to identify the HW at 2MHz:
+ * on success:
+ * * controller clock is >= 4 MHz
+ * * this may be 4MHz
+ * on failure:
+ * * controller clock is < 4 MHz
+ * * try to identify the HW at 2.5MHz:
+ * on success:
+ * * controller clock is >= 5 MHz
+ * * this may not be 4MHz
+ * on failure:
+ * * controller clock is 4 MHz
+ * * enable PLL
+ * * exit successfully (or run last test for verification purposes)
+ * * try to identify the HW at <dt-clock/2> MHz:
+ * on success:
+ * * controller clock is >= <dt-clock/2> MHz
+ * (it could be higher though)
+ * on failure:
+ * * the controller is not running at the
+ * clock rate configured in the DT
+ * * if PLL is enabled warn about requirements of POR
+ * * fail
+ *
+ * Side-effects:
+ * * longer initialization time
+ *
+ * Possible issues with mitigation:
+ * * possibly miss-identification because the SPI block may work
+ * "somewhat" at frequencies > < clock / 2 + delta f>
+ * this may be especially true for the situation where we test if
+ * 2.5MHz SPI-Clock works.
+ * * also SPI HW-clock dividers may do a round down to fixed frequencies
+ * which is not properly reported and may result in false positives
+ * because a frequency lower than expected is used.
+ *
+ * This is the reason why only simple testing is enabled at the risk of
+ * the need for a POR.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_can.h"
+#include "mcp25xxfd_clock.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_priv.h"
+
+/* the PLL may take some time to synchronize - use 1 second as timeout */
+#define MCP25XXFD_OSC_POLLING_JIFFIES (HZ)
+
+static u32 _mcp25xxfd_clkout_mask(struct mcp25xxfd_priv *priv)
+{
+ u32 val = 0;
+
+ if (priv->config.clock_div2)
+ val |= MCP25XXFD_OSC_SCLKDIV;
+
+ switch (priv->config.clock_odiv) {
+ case 0:
+ break;
+ case 1:
+ val |= MCP25XXFD_OSC_CLKODIV_1 << MCP25XXFD_OSC_CLKODIV_SHIFT;
+ break;
+ case 2:
+ val |= MCP25XXFD_OSC_CLKODIV_2 << MCP25XXFD_OSC_CLKODIV_SHIFT;
+ break;
+ case 4:
+ val |= MCP25XXFD_OSC_CLKODIV_4 << MCP25XXFD_OSC_CLKODIV_SHIFT;
+ break;
+ case 10:
+ val |= MCP25XXFD_OSC_CLKODIV_10 << MCP25XXFD_OSC_CLKODIV_SHIFT;
+ break;
+ default:
+ /* this should never happen but is error-handled
+ * by the dt-parsing
+ */
+ break;
+ }
+
+ return val;
+}
+
+static int _mcp25xxfd_waitfor_osc(struct mcp25xxfd_priv *priv,
+ u32 waitfor, u32 mask)
+{
+ unsigned long timeout;
+ int ret;
+
+ /* wait for synced pll/osc/sclk */
+ timeout = jiffies + MCP25XXFD_OSC_POLLING_JIFFIES;
+ while (time_before_eq(jiffies, timeout)) {
+ ret = mcp25xxfd_cmd_read(priv->spi, MCP25XXFD_OSC,
+ &priv->regs.osc);
+ if (ret)
+ return ret;
+ /* check for expected bits to be set/unset */
+ if ((priv->regs.osc & mask) == waitfor)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int _mcp25xxfd_clock_configure_osc(struct mcp25xxfd_priv *priv,
+ u32 value, u32 waitfor, u32 mask)
+{
+ int ret;
+
+ /* write the osc value to the controller - waking it if necessary */
+ ret = mcp25xxfd_cmd_write(priv->spi, MCP25XXFD_OSC, value);
+ if (ret)
+ return ret;
+
+ /* wait for the clock to stabelize */
+ ret = _mcp25xxfd_waitfor_osc(priv, waitfor, mask);
+
+ /* on timeout try again setting the register */
+ if (ret == -ETIMEDOUT) {
+ /* write the clock to the controller */
+ ret = mcp25xxfd_cmd_write(priv->spi, MCP25XXFD_OSC, value);
+ if (ret)
+ return ret;
+
+ /* wait for the clock to stabelize */
+ ret = _mcp25xxfd_waitfor_osc(priv, waitfor, mask);
+ }
+
+ /* handle timeout special - report the fact */
+ if (ret == -ETIMEDOUT)
+ dev_err(&priv->spi->dev,
+ "Clock did not switch within the timeout period\n");
+
+ return ret;
+}
+
+static int _mcp25xxfd_clock_start(struct mcp25xxfd_priv *priv)
+{
+ u32 value = _mcp25xxfd_clkout_mask(priv);
+ u32 waitfor = MCP25XXFD_OSC_OSCRDY;
+ u32 mask = waitfor | MCP25XXFD_OSC_OSCDIS | MCP25XXFD_OSC_PLLRDY |
+ MCP25XXFD_OSC_PLLEN;
+
+ /* enable PLL as well - set expectations */
+ if (priv->config.clock_pll) {
+ value |= MCP25XXFD_OSC_PLLEN;
+ waitfor |= MCP25XXFD_OSC_PLLRDY | MCP25XXFD_OSC_PLLEN;
+ }
+
+ /* set the oscilator now */
+ return _mcp25xxfd_clock_configure_osc(priv, value, waitfor, mask);
+}
+
+static int _mcp25xxfd_clock_stop(struct mcp25xxfd_priv *priv)
+{
+ u32 value = _mcp25xxfd_clkout_mask(priv);
+ u32 waitfor = 0;
+ u32 mask = MCP25XXFD_OSC_OSCDIS | MCP25XXFD_OSC_PLLRDY |
+ MCP25XXFD_OSC_PLLEN;
+ int ret;
+
+ ret = _mcp25xxfd_clock_configure_osc(priv, value, waitfor, mask);
+ if (ret)
+ return ret;
+
+ /* finally switch the controller mode to sleep
+ * by this time the controller should be in config mode already
+ * this way we wake to config mode again
+ */
+ return mcp25xxfd_can_sleep_mode(priv);
+}
+
+int mcp25xxfd_clock_start(struct mcp25xxfd_priv *priv, int requestor_mask)
+{
+ int ret = 0;
+
+ /* without a clock there is nothing we can do... */
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ mutex_lock(&priv->clk_user_lock);
+
+ /* if clock is already started, then skip */
+ if (priv->clk_user_mask & requestor_mask)
+ goto out;
+
+ /* enable the clock on the host side*/
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ goto out;
+
+ /* enable the clock on the controller side */
+ ret = _mcp25xxfd_clock_start(priv);
+ if (ret)
+ goto out;
+
+ /* mark the clock for the specific component as started */
+ priv->clk_user_mask |= requestor_mask;
+
+ /* and now we use the normal spi speed */
+ priv->spi_use_speed_hz = priv->spi_normal_speed_hz;
+
+out:
+ mutex_unlock(&priv->clk_user_lock);
+
+ return ret;
+}
+
+int mcp25xxfd_clock_stop(struct mcp25xxfd_priv *priv, int requestor_mask)
+{
+ int ret;
+
+ /* keep the clock on if explicitely configured */
+ if (priv->config.clock_allways_on)
+ return 0;
+
+ /* without a clock there is nothing we can do... */
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ mutex_lock(&priv->clk_user_lock);
+
+ /* if the mask is empty then skip, as the clock is stopped */
+ if (!priv->clk_user_mask)
+ goto out;
+
+ /* clear the clock mask */
+ priv->clk_user_mask &= ~requestor_mask;
+
+ /* if the mask is not empty then skip, as the clock is needed */
+ if (priv->clk_user_mask)
+ goto out;
+
+ /* and now we use the setup spi speed */
+ priv->spi_use_speed_hz = priv->spi_setup_speed_hz;
+
+ /* stop the clock on the controller */
+ ret = _mcp25xxfd_clock_stop(priv);
+
+ /* and we stop the clock on the host*/
+ if (!IS_ERR(priv->clk))
+ clk_disable_unprepare(priv->clk);
+out:
+ mutex_unlock(&priv->clk_user_lock);
+
+ return 0;
+}
+
+static int _mcp25xxfd_clock_probe(struct mcp25xxfd_priv *priv)
+{
+ int ret;
+
+ /* Wait for oscillator startup timer after power up */
+ mdelay(MCP25XXFD_OST_DELAY_MS);
+
+ /* send a "blind" reset, hoping we are in Config mode */
+ mcp25xxfd_cmd_reset(priv->spi);
+
+ /* Wait for oscillator startup again */
+ mdelay(MCP25XXFD_OST_DELAY_MS);
+
+ /* check clock register that the clock is ready or disabled */
+ ret = mcp25xxfd_cmd_read_regs(priv->spi, MCP25XXFD_OSC |
+ MCP25XXFD_ADDRESS_WITH_CRC,
+ &priv->regs.osc, 4);
+ if (ret == -EILSEQ)
+ dev_err(&priv->spi->dev,
+ "CRC read of clock register resulted in a bad CRC mismatch - hw not found\n");
+
+ if (ret)
+ return ret;
+
+ /* there can only be one... */
+ switch (priv->regs.osc &
+ (MCP25XXFD_OSC_OSCRDY | MCP25XXFD_OSC_OSCDIS)) {
+ case MCP25XXFD_OSC_OSCRDY: /* either the clock is ready */
+ break;
+ case MCP25XXFD_OSC_OSCDIS: /* or the clock is disabled */
+ break;
+ default:
+ /* otherwise there is no valid device (or in strange state)
+ *
+ * if PLL is enabled but not ready, then there may be
+ * something "fishy"
+ * this happened during driver development
+ * (enabling pll, when when on wrong clock), so best warn
+ * about such a possibility
+ */
+ if ((priv->regs.osc &
+ (MCP25XXFD_OSC_PLLEN | MCP25XXFD_OSC_PLLRDY))
+ == MCP25XXFD_OSC_PLLEN)
+ dev_err(&priv->spi->dev,
+ "mcp25xxfd may be in a strange state - a power disconnect may be required\n");
+
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int mcp25xxfd_clock_probe(struct mcp25xxfd_priv *priv)
+{
+ int ret;
+
+ /* this will also enable the MCP25XXFD_CLK_USER_CAN clock */
+ ret = _mcp25xxfd_clock_probe(priv);
+
+ /* on error retry a second time */
+ if (ret == -ENODEV) {
+ ret = _mcp25xxfd_clock_probe(priv);
+ if (!ret)
+ dev_info(&priv->spi->dev,
+ "found device only during retry\n");
+ }
+ if (ret) {
+ if (ret == -ENODEV)
+ dev_err(&priv->spi->dev,
+ "Cannot initialize MCP%x. Wrong wiring? (oscilator register reads as %08x)\n",
+ priv->model, priv->regs.osc);
+ }
+
+ return ret;
+}
+
+void mcp25xxfd_clock_release(struct mcp25xxfd_priv *priv)
+{
+ if (!IS_ERR_OR_NULL(priv->clk))
+ clk_disable_unprepare(priv->clk);
+}
+
+#ifdef CONFIG_OF_DYNAMIC
+static int mcp25xxfd_clock_of_parse(struct mcp25xxfd_priv *priv)
+{
+ struct spi_device *spi = priv->spi;
+ const struct device_node *np = spi->dev.of_node;
+ u32 val;
+ int ret;
+
+ priv->config.clock_div2 =
+ of_property_read_bool(np, "microchip,clock-div2");
+
+ priv->config.clock_allways_on =
+ of_property_read_bool(np, "microchip,clock-allways-on");
+
+ priv->config.clock_odiv = 10;
+ ret = of_property_read_u32_index(np, "microchip,clock-out-div",
+ 0, &val);
+ if (!ret) {
+ switch (val) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 10:
+ priv->config.clock_odiv = val;
+ break;
+ default:
+ dev_err(&spi->dev,
+ "Invalid value in device tree for microchip,clock_out_div: %u - valid values: 0, 1, 2, 4, 10\n",
+ val);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+#else
+static int mcp25xxfd_clock_of_parse(struct mcp25xxfd_priv *priv)
+{
+ return 0;
+}
+#endif
+
+int mcp25xxfd_clock_init(struct mcp25xxfd_priv *priv)
+{
+ struct spi_device *spi = priv->spi;
+ struct clk *clk;
+ int ret, freq;
+
+ mutex_init(&priv->clk_user_lock);
+
+ priv->config.clock_div2 = false;
+ priv->config.clock_allways_on = false;
+ priv->config.clock_odiv = 10;
+
+ ret = mcp25xxfd_clock_of_parse(priv);
+ if (ret)
+ return ret;
+
+ /* get clock */
+ clk = devm_clk_get(&spi->dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ freq = clk_get_rate(clk);
+ if (freq < MCP25XXFD_MIN_CLOCK_FREQUENCY ||
+ freq > MCP25XXFD_MAX_CLOCK_FREQUENCY) {
+ dev_err(&spi->dev,
+ "Clock frequency %i is not in range [%i:%i]\n",
+ freq,
+ MCP25XXFD_MIN_CLOCK_FREQUENCY,
+ MCP25XXFD_MAX_CLOCK_FREQUENCY);
+ return -ERANGE;
+ }
+
+ /* enable the clock and mark as enabled */
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return ret;
+ priv->clk = clk;
+
+ /* if we have a clock that is <= 4MHz, enable the pll */
+ priv->config.clock_pll =
+ (freq <= MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY);
+
+ /* decide on the effective clock rate */
+ priv->clock_freq = freq;
+ if (priv->config.clock_pll)
+ priv->clock_freq *= MCP25XXFD_PLL_MULTIPLIER;
+ if (priv->config.clock_div2)
+ priv->clock_freq /= MCP25XXFD_SCLK_DIVIDER;
+
+ /* calculate the clock frequencies to use
+ *
+ * setup clock speed is at most 1/4 the input clock speed
+ * the reason for the factor of 4 is that there is
+ * a clock divider in the controller that MAY be enabled in some
+ * circumstances so we may find a controller with that enabled
+ * during probe phase
+ */
+ priv->spi_setup_speed_hz = freq / 4;
+
+ /* normal operation clock speeds */
+ priv->spi_normal_speed_hz = priv->clock_freq / 2;
+ if (priv->config.clock_div2) {
+ priv->spi_setup_speed_hz /= MCP25XXFD_SCLK_DIVIDER;
+ priv->spi_normal_speed_hz /= MCP25XXFD_SCLK_DIVIDER;
+ }
+
+ /* set limit on speed */
+ if (spi->max_speed_hz) {
+ priv->spi_setup_speed_hz = min_t(int,
+ priv->spi_setup_speed_hz,
+ spi->max_speed_hz);
+ priv->spi_normal_speed_hz = min_t(int,
+ priv->spi_normal_speed_hz,
+ spi->max_speed_hz);
+ }
+
+ /* use setup speed by default
+ * - this is switched when clock is enabled/disabled
+ */
+ priv->spi_use_speed_hz = priv->spi_setup_speed_hz;
+
+ return 0;
+}
+
+void mcp25xxfd_clock_fake_sleep(struct mcp25xxfd_priv *priv)
+{
+ priv->regs.osc &= ~(MCP25XXFD_OSC_OSCRDY |
+ MCP25XXFD_OSC_PLLRDY |
+ MCP25XXFD_OSC_SCLKRDY);
+ priv->regs.osc |= MCP25XXFD_OSC_OSCDIS;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.h
new file mode 100644
index 000000000000..049e95cfa9ad
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_clock.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CLOCK_H
+#define __MCP25XXFD_CLOCK_H
+
+#include "mcp25xxfd_priv.h"
+
+#define MCP25XXFD_CLK_USER_CAN BIT(0)
+#define MCP25XXFD_CLK_USER_GPIO0 BIT(1)
+#define MCP25XXFD_CLK_USER_GPIO1 BIT(2)
+#define MCP25XXFD_CLK_USER_CLKOUT BIT(3)
+
+/* shared (internal) clock control */
+int mcp25xxfd_clock_init(struct mcp25xxfd_priv *priv);
+int mcp25xxfd_clock_probe(struct mcp25xxfd_priv *priv);
+void mcp25xxfd_clock_release(struct mcp25xxfd_priv *priv);
+
+int mcp25xxfd_clock_stop(struct mcp25xxfd_priv *priv, int requestor_mask);
+int mcp25xxfd_clock_start(struct mcp25xxfd_priv *priv, int requestor_mask);
+
+void mcp25xxfd_clock_fake_sleep(struct mcp25xxfd_priv *priv);
+
+#endif /* __MCP25XXFD_CLOCK_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.c
new file mode 100644
index 000000000000..81a4ff49ebc6
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_crc.h"
+#include "mcp25xxfd_priv.h"
+
+/* module parameter */
+static bool use_spi_crc;
+module_param(use_spi_crc, bool, 0664);
+MODULE_PARM_DESC(use_spi_crc, "Use SPI CRC instruction\n");
+
+/* SPI helper */
+
+/* wrapper arround spi_sync, that sets speed_hz */
+static int mcp25xxfd_cmd_sync_transfer(struct spi_device *spi,
+ struct spi_transfer *xfer,
+ unsigned int xfers)
+{
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+ int i;
+
+ for (i = 0; i < xfers; i++)
+ xfer[i].speed_hz = priv->spi_use_speed_hz;
+
+ return spi_sync_transfer(spi, xfer, xfers);
+}
+
+/* simple spi_write wrapper with speed_hz
+ * WARINING: tx_buf needs to be on heap!
+ */
+static int mcp25xxfd_cmd_sync_write(struct spi_device *spi,
+ const void *tx_buf,
+ unsigned len)
+{
+ struct spi_transfer xfer = {
+ .tx_buf = tx_buf,
+ .len = len,
+ };
+
+ return mcp25xxfd_cmd_sync_transfer(spi, &xfer, 1);
+}
+
+/* alloc buffer */
+static int mcp25xxfd_cmd_alloc_buf(struct spi_device *spi,
+ size_t len,
+ u8 **tx, u8 **rx)
+{
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+
+ /* allocate from heap in case the size is to big
+ * or the preallocated buffer is already used (i.e locked)
+ */
+ if (len > sizeof(priv->spi_tx) ||
+ !mutex_trylock(&priv->spi_rxtx_lock)) {
+ /* allocate tx+rx in one allocation if rx is requested */
+ *tx = kzalloc(rx ? 2 * len : len, GFP_KERNEL);
+ if (!*tx)
+ return -ENOMEM;
+ if (rx)
+ *rx = *tx + len;
+ } else {
+ /* use the preallocated buffers instead */
+ *tx = priv->spi_tx;
+ memset(priv->spi_tx, 0, sizeof(priv->spi_tx));
+ if (rx) {
+ *rx = priv->spi_rx;
+ memset(priv->spi_rx, 0, sizeof(priv->spi_rx));
+ }
+ }
+
+ return 0;
+}
+
+static void mcp25xxfd_cmd_release_buf(struct spi_device *spi, u8 *tx, u8 *rx)
+{
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+
+ if (tx == priv->spi_tx)
+ mutex_unlock(&priv->spi_rxtx_lock);
+ else
+ kfree(tx);
+}
+
+/* an optimization of spi_write_then_read that merges the transfers
+ * this also makes sure that the data is ALWAYS on heap
+ */
+static int mcp25xxfd_cmd_write_then_read(struct spi_device *spi,
+ const void *tx_buf,
+ unsigned int tx_len,
+ void *rx_buf,
+ unsigned int rx_len,
+ void *crc_buf)
+{
+ int crc_len = crc_buf ? 2 : 0;
+ struct spi_transfer xfer[2];
+ u8 *spi_tx, *spi_rx;
+ int xfers;
+ int ret;
+
+ /* get pointer to buffers */
+ ret = mcp25xxfd_cmd_alloc_buf(spi, tx_len + rx_len + crc_len,
+ &spi_tx, &spi_rx);
+ if (ret)
+ return ret;
+
+ /* clear the xfers */
+ memset(xfer, 0, sizeof(xfer));
+
+ /* special handling for half-duplex */
+ if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) {
+ xfers = 2;
+ xfer[0].tx_buf = spi_tx;
+ xfer[0].len = tx_len;
+ /* the offset for rx_buf needs to get aligned */
+ xfer[1].rx_buf = spi_rx + tx_len;
+ xfer[1].len = rx_len + crc_len;
+ } else {
+ xfers = 1;
+ xfer[0].len = tx_len + rx_len + crc_len;
+ xfer[0].tx_buf = spi_tx;
+ xfer[0].rx_buf = spi_rx;
+ }
+
+ /* copy data - especially to avoid buffers from stack */
+ memcpy(spi_tx, tx_buf, tx_len);
+
+ /* do the transfer */
+ ret = mcp25xxfd_cmd_sync_transfer(spi, xfer, xfers);
+ if (ret)
+ goto out;
+
+ /* copy result back */
+ memcpy(rx_buf, xfer[0].rx_buf + tx_len, rx_len);
+ if (crc_buf)
+ memcpy(crc_buf, xfer[0].rx_buf + tx_len + rx_len, crc_len);
+
+out:
+ mcp25xxfd_cmd_release_buf(spi, spi_tx, spi_rx);
+
+ return ret;
+}
+
+static int mcp25xxfd_cmd_write_then_write(struct spi_device *spi,
+ const void *tx_buf,
+ unsigned int tx_len,
+ const void *tx2_buf,
+ unsigned int tx2_len)
+{
+ struct spi_transfer xfer;
+ u8 *spi_tx;
+ int ret;
+
+ /* get pointer to buffers */
+ ret = mcp25xxfd_cmd_alloc_buf(spi, tx_len + tx2_len, &spi_tx, NULL);
+ if (ret)
+ return ret;
+
+ /* setup xfer */
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.len = tx_len + tx2_len;
+ xfer.tx_buf = spi_tx;
+
+ /* copy data to correct location in buffer */
+ memcpy(spi_tx, tx_buf, tx_len);
+ memcpy(spi_tx + tx_len, tx2_buf, tx2_len);
+
+ /* run the transfer */
+ ret = mcp25xxfd_cmd_sync_transfer(spi, &xfer, 1);
+
+ mcp25xxfd_cmd_release_buf(spi, spi_tx, NULL);
+
+ return ret;
+}
+
+/* mcp25xxfd spi command/protocol helper */
+
+/* read multiple bytes, transform some registers */
+int mcp25xxfd_cmd_readn(struct spi_device *spi, u32 reg,
+ void *data, int n)
+{
+ u8 cmd[2];
+
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_READ, reg, cmd);
+
+ return mcp25xxfd_cmd_write_then_read(spi, cmd, ARRAY_SIZE(cmd), data, n, NULL);
+}
+
+static u16 _mcp25xxfd_cmd_compute_crc(u8 *cmd, u8 *data, int n)
+{
+ u16 crc = 0xffff;
+
+ crc = mcp25xxfd_crc(crc, cmd, 3);
+ crc = mcp25xxfd_crc(crc, data, n);
+
+ return crc;
+}
+
+static int _mcp25xxfd_cmd_readn_crc(struct spi_device *spi, u32 reg,
+ void *data, int n)
+{
+ u8 cmd[3], crcd[2];
+ u16 crcc, crcr;
+ int ret;
+
+ /* prepare command */
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_READ_CRC, reg, cmd);
+ /* count depends on word (=RAM) or byte access (Registers) */
+ if (reg < MCP25XXFD_SRAM_ADDR(0) ||
+ reg >= MCP25XXFD_SRAM_ADDR(MCP25XXFD_SRAM_SIZE))
+ cmd[2] = n;
+ else
+ cmd[2] = n / 4;
+
+ /* now read for real */
+ ret = mcp25xxfd_cmd_write_then_read(spi, &cmd, 3, data, n, crcd);
+ if (ret)
+ return ret;
+
+ /* the received crc */
+ crcr = (crcd[0] << 8) + crcd[1];
+
+ /* compute the crc */
+ crcc = _mcp25xxfd_cmd_compute_crc(cmd, data, n);
+
+ /* if it matches, then return */
+ if (crcc == crcr)
+ return 0;
+
+ /* here possibly handle crc variants with a single bit7 flips */
+
+ /* return with error and rate limited */
+ dev_err_ratelimited(&spi->dev,
+ "CRC read error: computed: %04x received: %04x - data: %*ph %*ph%s\n",
+ crcc, crcr, 3, cmd, min_t(int, 64, n), data,
+ (n > 64) ? "..." : "");
+ return -EILSEQ;
+}
+
+static int mcp25xxfd_cmd_readn_crc(struct spi_device *spi, u32 reg,
+ void *data, int n)
+{
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
+#endif
+ int ret;
+
+ for (; n > 0; n -= 254, reg += 254, data += 254) {
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ priv->stats.spi_crc_read++;
+ if (n > 254)
+ priv->stats.spi_crc_read_split++;
+#endif
+ ret = _mcp25xxfd_cmd_readn_crc(spi, reg, data, n);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* read a register, but we are only interrested in a few bytes */
+int mcp25xxfd_cmd_read_mask(struct spi_device *spi, u32 reg,
+ u32 *data, u32 mask)
+{
+ int first_byte, last_byte, len_byte;
+ int ret;
+
+ /* check that at least one bit is set */
+ if (!mask)
+ return -EINVAL;
+
+ /* calculate first and last byte used */
+ first_byte = mcp25xxfd_cmd_first_byte(mask);
+ last_byte = mcp25xxfd_cmd_last_byte(mask);
+ len_byte = last_byte - first_byte + 1;
+
+ mcp25xxfd_cmd_convert_from_cpu(data, 1);
+
+ /* do a partial read */
+ ret = mcp25xxfd_cmd_readn(spi, reg + first_byte,
+ ((void *)data + first_byte), len_byte);
+ if (ret)
+ return ret;
+
+ mcp25xxfd_cmd_convert_to_cpu(data, 1);
+
+ return 0;
+}
+
+int mcp25xxfd_cmd_writen(struct spi_device *spi, u32 reg,
+ void *data, int n)
+{
+ u8 cmd[2];
+
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_WRITE, reg, cmd);
+
+ return mcp25xxfd_cmd_write_then_write(spi, &cmd, 2, data, n);
+}
+
+/* read a register, but we are only interrested in a few bytes */
+int mcp25xxfd_cmd_write_mask(struct spi_device *spi, u32 reg,
+ u32 data, u32 mask)
+{
+ int first_byte, last_byte, len_byte;
+ u8 cmd[2];
+
+ /* check that at least one bit is set */
+ if (!mask)
+ return -EINVAL;
+
+ /* calculate first and last byte used */
+ first_byte = mcp25xxfd_cmd_first_byte(mask);
+ last_byte = mcp25xxfd_cmd_last_byte(mask);
+ len_byte = last_byte - first_byte + 1;
+
+ /* prepare buffer */
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_WRITE,
+ reg + first_byte, cmd);
+
+ mcp25xxfd_cmd_convert_from_cpu(&data, 1);
+
+ return mcp25xxfd_cmd_write_then_write(spi,
+ cmd, sizeof(cmd),
+ ((void *)&data + first_byte),
+ len_byte);
+}
+
+int mcp25xxfd_cmd_write_regs(struct spi_device *spi, u32 reg,
+ u32 *data, u32 bytes)
+{
+ int ret;
+
+ /* first transpose to controller format */
+ mcp25xxfd_cmd_convert_from_cpu(data, bytes / sizeof(bytes));
+
+ /* now write it */
+ ret = mcp25xxfd_cmd_writen(spi, reg, data, bytes);
+
+ /* and convert it back to cpu format even if it fails */
+ mcp25xxfd_cmd_convert_to_cpu(data, bytes / sizeof(bytes));
+
+ return ret;
+}
+
+int mcp25xxfd_cmd_read_regs(struct spi_device *spi, u32 reg,
+ u32 *data, u32 bytes)
+{
+ int ret;
+
+ /* read it using crc */
+ if ((use_spi_crc) || (reg & MCP25XXFD_ADDRESS_WITH_CRC))
+ ret = mcp25xxfd_cmd_readn_crc(spi,
+ reg & MCP25XXFD_ADDRESS_MASK,
+ data, bytes);
+ else
+ ret = mcp25xxfd_cmd_readn(spi, reg, data, bytes);
+
+ /* and convert it to cpu format */
+ mcp25xxfd_cmd_convert_to_cpu((u32 *)data, bytes / sizeof(bytes));
+
+ return ret;
+}
+
+int mcp25xxfd_cmd_reset(struct spi_device *spi)
+{
+ u8 *cmd;
+ int ret;
+
+ /* allocate 2 bytes on heap, as we use sync_write */
+ cmd = kzalloc(2, GFP_KERNEL);
+ if (!cmd)
+ return -ENOMEM;
+
+ mcp25xxfd_cmd_calc(MCP25XXFD_INSTRUCTION_RESET, 0, cmd);
+
+ /* write the reset command */
+ ret = mcp25xxfd_cmd_sync_write(spi, cmd, 2);
+
+ kfree(cmd);
+
+ return ret;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.h
new file mode 100644
index 000000000000..a60a14c4f3b7
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_cmd.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_CMD_H
+#define __MCP25XXFD_CMD_H
+
+#include <linux/byteorder/generic.h>
+#include <linux/spi/spi.h>
+
+/* SPI commands */
+#define MCP25XXFD_INSTRUCTION_RESET 0x0000
+#define MCP25XXFD_INSTRUCTION_READ 0x3000
+#define MCP25XXFD_INSTRUCTION_WRITE 0x2000
+#define MCP25XXFD_INSTRUCTION_READ_CRC 0xB000
+#define MCP25XXFD_INSTRUCTION_WRITE_CRC 0xA000
+#define MCP25XXFD_INSTRUCTION_WRITE_SAVE 0xC000
+
+#define MCP25XXFD_ADDRESS_MASK 0x0fff
+/* a bit to use CRC commands if possible */
+#define MCP25XXFD_ADDRESS_WITH_CRC BIT(31)
+
+static inline void mcp25xxfd_cmd_convert_to_cpu(u32 *data, int n)
+{
+ le32_to_cpu_array(data, n);
+}
+
+static inline void mcp25xxfd_cmd_convert_from_cpu(u32 *data, int n)
+{
+ cpu_to_le32_array(data, n);
+}
+
+static inline void mcp25xxfd_cmd_calc(u16 cmd, u16 addr, u8 *data)
+{
+ cmd |= addr & MCP25XXFD_ADDRESS_MASK;
+
+ data[0] = cmd >> 8;
+ data[1] = cmd;
+}
+
+static inline int mcp25xxfd_cmd_first_byte(u32 mask)
+{
+ return (mask & 0x0000ffff) ?
+ ((mask & 0x000000ff) ? 0 : 1) :
+ ((mask & 0x00ff0000) ? 2 : 3);
+}
+
+static inline int mcp25xxfd_cmd_last_byte(u32 mask)
+{
+ return (mask & 0xffff0000) ?
+ ((mask & 0xff000000) ? 3 : 2) :
+ ((mask & 0x0000ff00) ? 1 : 0);
+}
+
+int mcp25xxfd_cmd_readn(struct spi_device *spi, u32 reg,
+ void *data, int n);
+int mcp25xxfd_cmd_read_mask(struct spi_device *spi, u32 reg,
+ u32 *data, u32 mask);
+static inline int mcp25xxfd_cmd_read(struct spi_device *spi, u32 reg,
+ u32 *data)
+{
+ return mcp25xxfd_cmd_read_mask(spi, reg, data, -1);
+}
+
+int mcp25xxfd_cmd_read_regs(struct spi_device *spi, u32 reg,
+ u32 *data, u32 bytes);
+
+int mcp25xxfd_cmd_writen(struct spi_device *spi, u32 reg,
+ void *data, int n);
+int mcp25xxfd_cmd_write_mask(struct spi_device *spi, u32 reg,
+ u32 data, u32 mask);
+static inline int mcp25xxfd_cmd_write(struct spi_device *spi, u32 reg,
+ u32 data)
+{
+ return mcp25xxfd_cmd_write_mask(spi, reg, data, -1);
+}
+
+int mcp25xxfd_cmd_write_regs(struct spi_device *spi, u32 reg,
+ u32 *data, u32 bytes);
+
+int mcp25xxfd_cmd_reset(struct spi_device *spi);
+
+#endif /* __MCP25XXFD_CMD_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.c
new file mode 100644
index 000000000000..466f989845dd
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_crc.h"
+#include "mcp25xxfd_regs.h"
+#include "mcp25xxfd_priv.h"
+
+/* the standard crc16 in linux/crc16.h is unfortunately not
+ * computing the correct results (left shift vs. right shift)
+ * so here an implementation with a table generated by:
+ * http://lkml.iu.edu/hypermail/linux/kernel/0508.1/1085.html
+ *
+ * if someone has a better idea how to make crc16 produce the expected
+ * result, then please come forward...
+ */
+static const u16 _mcp25xxfd_crc_table[256] = {
+ 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
+ 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
+ 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
+ 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
+ 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
+ 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
+ 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
+ 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
+ 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
+ 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
+ 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
+ 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
+ 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
+ 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
+ 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
+ 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
+ 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
+ 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
+ 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
+ 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
+ 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
+ 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
+ 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
+ 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
+ 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
+ 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
+ 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
+ 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
+ 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
+ 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
+ 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
+ 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
+};
+
+static inline u16 mcp25xxfd_crc_byte(u16 crc, const u8 data)
+{
+ u8 index = (crc >> 8) ^ data;
+
+ return (crc << 8) ^ _mcp25xxfd_crc_table[index];
+}
+
+u16 mcp25xxfd_crc(u16 crc, u8 const *buffer, size_t len)
+{
+ while (len--)
+ crc = mcp25xxfd_crc_byte(crc, *buffer++);
+ return crc;
+}
+
+int mcp25xxfd_crc_enable_int(struct mcp25xxfd_priv *priv, bool enable)
+{
+ u32 mask = MCP25XXFD_CRC_CRCERRIE | MCP25XXFD_CRC_FERRIE;
+
+ priv->regs.crc &= ~mask;
+ priv->regs.crc |= enable ? mask : 0;
+
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_CRC,
+ priv->regs.crc, mask);
+}
+
+int mcp25xxfd_crc_clear_int(struct mcp25xxfd_priv *priv)
+{
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_CRC, 0,
+ MCP25XXFD_CRC_CRCERRIF |
+ MCP25XXFD_CRC_FERRIF);
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.h
new file mode 100644
index 000000000000..25db96b0b9c9
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_crc.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_CRC_H
+#define __MCP25XXFD_CRC_H
+
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_crc_enable_int(struct mcp25xxfd_priv *priv, bool enable);
+int mcp25xxfd_crc_clear_int(struct mcp25xxfd_priv *priv);
+
+u16 mcp25xxfd_crc(u16 crc, u8 const *buffer, size_t len);
+
+#endif /* __MCP25XXFD_CRC_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.c
new file mode 100644
index 000000000000..20969c76db46
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_debugfs.h"
+#include "mcp25xxfd_priv.h"
+
+static int mcp25xxfd_debugfs_dump_regs_range(struct seq_file *file,
+ u32 start, u32 end)
+{
+ struct spi_device *spi = file->private;
+ u32 data[32];
+ int bytes = end - start + sizeof(*data);
+ int i, l, count, ret;
+
+ for (count = bytes / sizeof(*data); count > 0; count -= 32) {
+ /* read up to 32 registers in one go */
+ l = min(count, 32);
+ ret = mcp25xxfd_cmd_read_regs(spi, start,
+ data, l * sizeof(*data));
+ if (ret)
+ return ret;
+ /* dump those read registers */
+ for (i = 0; i < l; i++, start += sizeof(*data))
+ seq_printf(file, "Reg 0x%03x = 0x%08x\n",
+ start, data[i]);
+ }
+
+ return 0;
+}
+
+static int mcp25xxfd_debugfs_dump_regs(struct seq_file *file, void *offset)
+{
+ return mcp25xxfd_debugfs_dump_regs_range(file, MCP25XXFD_OSC,
+ MCP25XXFD_DEVID);
+}
+
+static int mcp25xxfd_debugfs_dump_can_regs(struct seq_file *file,
+ void *offset)
+{
+ return mcp25xxfd_debugfs_dump_regs_range(file, MCP25XXFD_CAN_CON,
+ MCP25XXFD_CAN_TXQUA);
+}
+
+static int mcp25xxfd_debugfs_dump_can_all_regs(struct seq_file *file,
+ void *offset)
+{
+ return mcp25xxfd_debugfs_dump_regs_range(file, MCP25XXFD_CAN_CON,
+ MCP25XXFD_CAN_FLTMASK(31));
+}
+
+static void mcp25xxfd_debugfs_mod_setup(struct mcp25xxfd_priv *priv)
+{
+ struct dentry *root, *regs;
+
+ /* the base directory */
+ priv->debugfs_dir = debugfs_create_dir(priv->device_name, NULL);
+ root = priv->debugfs_dir;
+
+ /* expose some parameters related to clocks */
+ debugfs_create_u32("spi_setup_speed_hz", 0644, root,
+ &priv->spi_setup_speed_hz);
+ debugfs_create_u32("spi_normal_speed_hz", 0644, root,
+ &priv->spi_normal_speed_hz);
+ debugfs_create_u32("spi_use_speed_hz", 0644, root,
+ &priv->spi_use_speed_hz);
+ debugfs_create_u32("clk_user_mask", 0444, root, &priv->clk_user_mask);
+
+ /* some statistics */
+ debugfs_create_u64("spi_crc_read", 0444, root,
+ &priv->stats.spi_crc_read);
+ debugfs_create_u64("spi_crc_read_split", 0444, root,
+ &priv->stats.spi_crc_read_split);
+
+ /* expose the system registers */
+ priv->debugfs_regs_dir = debugfs_create_dir("regs", root);
+ regs = priv->debugfs_regs_dir;
+ debugfs_create_x32("osc", 0444, regs, &priv->regs.osc);
+ debugfs_create_x32("iocon", 0444, regs, &priv->regs.iocon);
+ debugfs_create_x32("crc", 0444, regs, &priv->regs.crc);
+ debugfs_create_x32("ecccon", 0444, regs, &priv->regs.ecccon);
+
+ /* dump the controller registers themselves */
+ debugfs_create_devm_seqfile(&priv->spi->dev, "regs_live_dump",
+ root, mcp25xxfd_debugfs_dump_regs);
+ /* and the essential can registers */
+ debugfs_create_devm_seqfile(&priv->spi->dev, "can_regs_live_dump",
+ root, mcp25xxfd_debugfs_dump_can_regs);
+ /* and the complete can registers */
+ debugfs_create_devm_seqfile(&priv->spi->dev,
+ "can_regs_all_live_dump", root,
+ mcp25xxfd_debugfs_dump_can_all_regs);
+}
+
+void mcp25xxfd_debugfs_setup(struct mcp25xxfd_priv *priv)
+{
+ mcp25xxfd_debugfs_mod_setup(priv);
+}
+
+void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv)
+{
+ debugfs_remove_recursive(priv->debugfs_dir);
+ priv->debugfs_dir = NULL;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.h
new file mode 100644
index 000000000000..905f15ea7f5d
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_debugfs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_DEBUGFS_H
+#define __MCP25XXFD_DEBUGFS_H
+
+#include "mcp25xxfd_priv.h"
+
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+
+void mcp25xxfd_debugfs_setup(struct mcp25xxfd_priv *priv);
+void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv);
+
+#else
+
+static inline void mcp25xxfd_debugfs_setup(struct mcp25xxfd_priv *priv)
+{
+}
+
+static inline void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv)
+{
+}
+
+#endif /* CONFIG_CAN_MCP25XXFD_DEBUG_FS */
+#endif /* __MCP25XXFD_DEBUGFS_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.c
new file mode 100644
index 000000000000..526f345d0a17
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_ecc.h"
+#include "mcp25xxfd_priv.h"
+#include "mcp25xxfd_regs.h"
+
+int mcp25xxfd_ecc_clear_int(struct mcp25xxfd_priv *priv)
+{
+ u32 val, addr;
+ int ret;
+
+ /* first report the error address */
+ ret = mcp25xxfd_cmd_read(priv->spi, MCP25XXFD_ECCSTAT, &val);
+ if (ret)
+ return ret;
+
+ /* if no flags are set then nothing to do */
+ if (!(val & (MCP25XXFD_ECCSTAT_SECIF | MCP25XXFD_ECCSTAT_DEDIF)))
+ return 0;
+
+ addr = (val & MCP25XXFD_ECCSTAT_ERRADDR_MASK) >>
+ MCP25XXFD_ECCSTAT_ERRADDR_SHIFT;
+
+ dev_err_ratelimited(&priv->spi->dev, "ECC %s bit error at %03x\n",
+ (val & MCP25XXFD_ECCSTAT_DEDIF) ?
+ "double" : "single",
+ addr);
+
+ /* and clear the error */
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_ECCSTAT, 0,
+ MCP25XXFD_ECCSTAT_SECIF |
+ MCP25XXFD_ECCSTAT_DEDIF);
+}
+
+int mcp25xxfd_ecc_enable_int(struct mcp25xxfd_priv *priv, bool enable)
+{
+ u32 mask = MCP25XXFD_ECCCON_SECIE | MCP25XXFD_ECCCON_DEDIE;
+
+ priv->regs.ecccon &= ~mask;
+ priv->regs.ecccon |= MCP25XXFD_ECCCON_ECCEN | (enable ? mask : 0);
+
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_ECCCON,
+ priv->regs.ecccon,
+ MCP25XXFD_ECCCON_ECCEN | mask);
+}
+
+int mcp25xxfd_ecc_enable(struct mcp25xxfd_priv *priv)
+{
+ u8 buffer[256];
+ int i, ret;
+
+ /* set up RAM ECC - enable interrupts sets it as well */
+ ret = mcp25xxfd_ecc_enable_int(priv, false);
+ if (ret)
+ return ret;
+
+ /* and clear SRAM so that no reads fails from now on */
+ memset(buffer, 0, sizeof(buffer));
+ for (i = 0; i < MCP25XXFD_SRAM_SIZE; i += sizeof(buffer)) {
+ ret = mcp25xxfd_cmd_writen(priv->spi, MCP25XXFD_SRAM_ADDR(i),
+ buffer, sizeof(buffer));
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.h
new file mode 100644
index 000000000000..117f58c65a46
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_ecc.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_ECC_H
+#define __MCP25XXFD_ECC_H
+
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_ecc_clear_int(struct mcp25xxfd_priv *priv);
+int mcp25xxfd_ecc_enable_int(struct mcp25xxfd_priv *priv, bool enable);
+int mcp25xxfd_ecc_enable(struct mcp25xxfd_priv *priv);
+
+#endif /* __MCP25XXFD_ECC_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.c
new file mode 100644
index 000000000000..5bda9d8a6e7e
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ *
+ * Based on Microchip MCP251x CAN controller driver written by
+ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "mcp25xxfd_clock.h"
+#include "mcp25xxfd_cmd.h"
+#include "mcp25xxfd_gpio.h"
+#include "mcp25xxfd_priv.h"
+
+static int mcp25xxfd_gpio_request(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ int clock_requestor = offset ?
+ MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return -EINVAL;
+
+ /* if we have XSTANDBY enabled then gpio0 is not available either */
+ if (priv->config.gpio0_xstandby && offset == 0)
+ return -EINVAL;
+
+ mcp25xxfd_clock_start(priv, clock_requestor);
+
+ return 0;
+}
+
+static void mcp25xxfd_gpio_free(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ int clock_requestor = offset ?
+ MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return;
+
+ mcp25xxfd_clock_stop(priv, clock_requestor);
+}
+
+static int mcp25xxfd_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask = (offset) ? MCP25XXFD_IOCON_GPIO1 : MCP25XXFD_IOCON_GPIO0;
+ int ret;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return -EINVAL;
+
+ /* read the relevant gpio Latch */
+ ret = mcp25xxfd_cmd_read_mask(priv->spi, MCP25XXFD_IOCON,
+ &priv->regs.iocon, mask);
+ if (ret)
+ return ret;
+
+ /* return the match */
+ return priv->regs.iocon & mask;
+}
+
+static void mcp25xxfd_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask = (offset) ? MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return;
+
+ /* update in memory representation with the corresponding value */
+ if (value)
+ priv->regs.iocon |= mask;
+ else
+ priv->regs.iocon &= ~mask;
+
+ mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON,
+ priv->regs.iocon, mask);
+}
+
+static int mcp25xxfd_gpio_direction_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask_tri = (offset) ?
+ MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0;
+ u32 mask_stby = (offset) ?
+ 0 : MCP25XXFD_IOCON_XSTBYEN;
+ u32 mask_pm = (offset) ?
+ MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return -EINVAL;
+
+ /* set the mask */
+ priv->regs.iocon |= mask_tri | mask_pm;
+
+ /* clear stby */
+ priv->regs.iocon &= ~mask_stby;
+
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON,
+ priv->regs.iocon,
+ mask_tri | mask_stby | mask_pm);
+}
+
+static int mcp25xxfd_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask_tri = (offset) ?
+ MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0;
+ u32 mask_lat = (offset) ?
+ MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0;
+ u32 mask_pm = (offset) ?
+ MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0;
+ u32 mask_stby = (offset) ?
+ 0 : MCP25XXFD_IOCON_XSTBYEN;
+
+ /* only handle gpio 0/1 */
+ if (offset > 1)
+ return -EINVAL;
+
+ /* clear the tristate bit and also clear stby */
+ priv->regs.iocon &= ~(mask_tri | mask_stby);
+
+ /* set GPIO mode */
+ priv->regs.iocon |= mask_pm;
+
+ /* set the value */
+ if (value)
+ priv->regs.iocon |= mask_lat;
+ else
+ priv->regs.iocon &= ~mask_lat;
+
+ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON,
+ priv->regs.iocon,
+ mask_tri | mask_lat |
+ mask_pm | mask_stby);
+}
+
+#ifdef CONFIG_OF_DYNAMIC
+static void mcp25xxfd_gpio_read_of(struct mcp25xxfd_priv *priv)
+{
+ const struct device_node *np = priv->spi->dev.of_node;
+
+ priv->config.gpio_open_drain =
+ of_property_read_bool(np, "microchip,gpio-open-drain");
+ priv->config.gpio0_xstandby =
+ of_property_read_bool(np, "microchip,gpio0-xstandby");
+}
+#else
+static void mcp25xxfd_gpio_read_of(struct mcp25xxfd_priv *priv)
+{
+ priv->config.gpio_open_drain = false;
+ priv->config.gpio0_xstandby = false;
+}
+#endif
+
+static int mcp25xxfd_gpio_setup_regs(struct mcp25xxfd_priv *priv)
+{
+ /* handle open-drain */
+ if (priv->config.gpio_open_drain)
+ priv->regs.iocon |= MCP25XXFD_IOCON_INTOD;
+ else
+ priv->regs.iocon &= ~MCP25XXFD_IOCON_INTOD;
+
+ /* handle xstandby */
+ if (priv->config.gpio0_xstandby) {
+ priv->regs.iocon &= ~(MCP25XXFD_IOCON_TRIS0 |
+ MCP25XXFD_IOCON_GPIO0);
+ priv->regs.iocon |= MCP25XXFD_IOCON_XSTBYEN;
+ } else {
+ priv->regs.iocon &= ~(MCP25XXFD_IOCON_XSTBYEN);
+ }
+
+ /* handle sof / clko */
+ if (priv->config.clock_odiv == 0)
+ priv->regs.iocon |= MCP25XXFD_IOCON_SOF;
+ else
+ priv->regs.iocon &= ~MCP25XXFD_IOCON_SOF;
+
+ /* update the iocon register */
+ return mcp25xxfd_cmd_write_regs(priv->spi, MCP25XXFD_IOCON,
+ &priv->regs.iocon, sizeof(u32));
+}
+
+static int mcp25xxfd_gpio_setup_gpiochip(struct mcp25xxfd_priv *priv)
+{
+ struct gpio_chip *gpio = &priv->gpio;
+
+ /* gpiochip only handles GPIO0 and GPIO1 */
+ gpio->owner = THIS_MODULE;
+ gpio->parent = &priv->spi->dev;
+ gpio->label = dev_name(&priv->spi->dev);
+ gpio->direction_input = mcp25xxfd_gpio_direction_input;
+ gpio->get = mcp25xxfd_gpio_get;
+ gpio->direction_output = mcp25xxfd_gpio_direction_output;
+ gpio->set = mcp25xxfd_gpio_set;
+ gpio->request = mcp25xxfd_gpio_request;
+ gpio->free = mcp25xxfd_gpio_free;
+ gpio->base = -1;
+ gpio->ngpio = 2;
+ gpio->can_sleep = 1;
+
+ return gpiochip_add_data(gpio, priv);
+}
+
+int mcp25xxfd_gpio_setup(struct mcp25xxfd_priv *priv)
+{
+ int ret;
+
+ /* setting up defaults */
+ priv->config.gpio0_xstandby = false;
+
+ mcp25xxfd_gpio_read_of(priv);
+ ret = mcp25xxfd_gpio_setup_regs(priv);
+ if (ret)
+ return ret;
+
+ return mcp25xxfd_gpio_setup_gpiochip(priv);
+}
+
+void mcp25xxfd_gpio_remove(struct mcp25xxfd_priv *priv)
+{
+ gpiochip_remove(&priv->gpio);
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.h
new file mode 100644
index 000000000000..cd4f0aa5e032
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_gpio.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_GPIO_H
+#define __MCP25XXFD_GPIO_H
+
+#include "mcp25xxfd_priv.h"
+
+#ifdef CONFIG_GPIOLIB
+
+/* gpiolib support */
+int mcp25xxfd_gpio_setup(struct mcp25xxfd_priv *priv);
+void mcp25xxfd_gpio_remove(struct mcp25xxfd_priv *priv);
+
+#else
+
+static inline int mcp25xxfd_gpio_setup(struct mcp25xxfd_priv *priv)
+{
+ return 0;
+}
+
+static inline void mcp25xxfd_gpio_remove(struct mcp25xxfd_priv *priv)
+{
+}
+
+#endif
+
+#endif /* __MCP25XXFD_GPIO_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.c
new file mode 100644
index 000000000000..cca9c996b542
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_can_int.h"
+#include "mcp25xxfd_crc.h"
+#include "mcp25xxfd_ecc.h"
+#include "mcp25xxfd_int.h"
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_int_clear(struct mcp25xxfd_priv *priv)
+{
+ int ret;
+
+ ret = mcp25xxfd_ecc_clear_int(priv);
+ if (ret)
+ return ret;
+ ret = mcp25xxfd_crc_clear_int(priv);
+ if (ret)
+ return ret;
+ ret = mcp25xxfd_can_int_clear(priv);
+
+ return ret;
+}
+
+int mcp25xxfd_int_enable(struct mcp25xxfd_priv *priv, bool enable)
+{
+ /* error handling only on enable for this function */
+ int ret = 0;
+
+ /* if we enable clear interrupt flags first */
+ if (enable) {
+ ret = mcp25xxfd_int_clear(priv);
+ if (ret)
+ goto out;
+ }
+
+ ret = mcp25xxfd_crc_enable_int(priv, enable);
+ if (ret)
+ goto out;
+
+ ret = mcp25xxfd_ecc_enable(priv);
+ if (ret)
+ goto out_crc;
+
+ ret = mcp25xxfd_ecc_enable_int(priv, enable);
+ if (ret)
+ goto out_crc;
+
+ ret = mcp25xxfd_can_int_enable(priv, enable);
+ if (ret)
+ goto out_ecc;
+
+ /* if we disable interrupts clear interrupt flags last */
+ if (!enable)
+ mcp25xxfd_int_clear(priv);
+
+ return 0;
+
+out_ecc:
+ mcp25xxfd_ecc_enable_int(priv, false);
+
+out_crc:
+ mcp25xxfd_crc_enable_int(priv, false);
+out:
+ return ret;
+}
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.h
new file mode 100644
index 000000000000..4daf0182d1af
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_int.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_INT_H
+#define __MCP25XXFD_INT_H
+
+#include "mcp25xxfd_priv.h"
+
+int mcp25xxfd_int_clear(struct mcp25xxfd_priv *priv);
+int mcp25xxfd_int_enable(struct mcp25xxfd_priv *priv, bool enable);
+
+#endif /* __MCP25XXFD_INT_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_priv.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_priv.h
new file mode 100644
index 000000000000..ced89e0b9e3c
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_priv.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+#ifndef __MCP25XXFD_PRIV_H
+#define __MCP25XXFD_PRIV_H
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/gpio/driver.h>
+#include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#include "mcp25xxfd_regs.h"
+
+/* some defines for the driver */
+#define DEVICE_NAME "mcp25xxfd"
+
+enum mcp25xxfd_model {
+ CAN_MCP2517FD = 0x2517,
+ CAN_MCP2518FD = 0x2518,
+};
+
+struct mcp25xxfd_can_priv;
+struct mcp25xxfd_priv {
+ struct spi_device *spi;
+ struct clk *clk;
+#ifdef CONFIG_GPIOLIB
+ struct gpio_chip gpio;
+#endif
+ struct mcp25xxfd_can_priv *cpriv;
+
+ /* the actual model of the mcp25xxfd */
+ enum mcp25xxfd_model model;
+
+ /* full device name used for debugfs and interrupts */
+ char device_name[32];
+
+ /* everything clock related */
+ int clock_freq;
+ struct {
+ /* clock configuration */
+ int clock_pll;
+ int clock_div2;
+ int clock_odiv;
+ int clock_allways_on;
+ /* gpio related */
+ bool gpio_open_drain;
+ bool gpio0_xstandby;
+ } config;
+
+ /* lock for enabling/disabling the clock */
+ struct mutex clk_user_lock;
+ u32 clk_user_mask;
+ u32 clk_sleep_mask;
+
+ /* power related */
+ struct regulator *power;
+
+ /* the distinct spi_speeds to use for spi communication */
+ u32 spi_setup_speed_hz;
+ u32 spi_normal_speed_hz;
+ u32 spi_use_speed_hz;
+
+ /* spi-tx/rx buffers for efficient transfers
+ * used during setup and irq
+ */
+ struct mutex spi_rxtx_lock; /* protects use of spi_tx/rx */
+ u8 spi_tx[MCP25XXFD_SRAM_SIZE];
+ u8 spi_rx[MCP25XXFD_SRAM_SIZE];
+
+ /* configuration registers */
+ struct {
+ u32 osc;
+ u32 iocon;
+ u32 crc;
+ u32 ecccon;
+ } regs;
+
+ /* debugfs related */
+#ifdef CONFIG_CAN_MCP25XXFD_DEBUG_FS
+ struct dentry *debugfs_dir;
+ struct dentry *debugfs_regs_dir;
+ struct {
+ u64 spi_crc_read;
+ u64 spi_crc_read_split;
+ } stats;
+#endif
+};
+
+#endif /* __MCP25XXFD_PRIV_H */
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_regs.h b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_regs.h
new file mode 100644
index 000000000000..80a166248955
--- /dev/null
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_regs.h
@@ -0,0 +1,681 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
+ *
+ * Copyright 2019 Martin Sperl <kernel@martin.sperl.org>
+ */
+
+#ifndef __MCP25XXFD_REGS_H
+#define __MCP25XXFD_REGS_H
+
+#include <linux/bitops.h>
+
+/* some constants derived from the datasheets */
+#define MCP25XXFD_OST_DELAY_MS 3
+#define MCP25XXFD_MIN_CLOCK_FREQUENCY 1000000
+#define MCP25XXFD_MAX_CLOCK_FREQUENCY 40000000
+#define MCP25XXFD_PLL_MULTIPLIER 10
+#define MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY \
+ (MCP25XXFD_MAX_CLOCK_FREQUENCY / MCP25XXFD_PLL_MULTIPLIER)
+#define MCP25XXFD_SCLK_DIVIDER 2
+
+/* GPIO, clock, ecc related register definitions of Controller itself */
+#define MCP25XXFD_SFR_BASE(x) (0xE00 + (x))
+#define MCP25XXFD_OSC MCP25XXFD_SFR_BASE(0x00)
+# define MCP25XXFD_OSC_PLLEN BIT(0)
+# define MCP25XXFD_OSC_OSCDIS BIT(2)
+# define MCP25XXFD_OSC_SCLKDIV BIT(4)
+# define MCP25XXFD_OSC_CLKODIV_BITS 2
+# define MCP25XXFD_OSC_CLKODIV_SHIFT 5
+# define MCP25XXFD_OSC_CLKODIV_MASK \
+ GENMASK(MCP25XXFD_OSC_CLKODIV_SHIFT \
+ + MCP25XXFD_OSC_CLKODIV_BITS - 1, \
+ MCP25XXFD_OSC_CLKODIV_SHIFT)
+# define MCP25XXFD_OSC_CLKODIV_10 3
+# define MCP25XXFD_OSC_CLKODIV_4 2
+# define MCP25XXFD_OSC_CLKODIV_2 1
+# define MCP25XXFD_OSC_CLKODIV_1 0
+# define MCP25XXFD_OSC_PLLRDY BIT(8)
+# define MCP25XXFD_OSC_OSCRDY BIT(10)
+# define MCP25XXFD_OSC_SCLKRDY BIT(12)
+#define MCP25XXFD_IOCON MCP25XXFD_SFR_BASE(0x04)
+# define MCP25XXFD_IOCON_TRIS0 BIT(0)
+# define MCP25XXFD_IOCON_TRIS1 BIT(1)
+# define MCP25XXFD_IOCON_XSTBYEN BIT(6)
+# define MCP25XXFD_IOCON_LAT0 BIT(8)
+# define MCP25XXFD_IOCON_LAT1 BIT(9)
+# define MCP25XXFD_IOCON_GPIO0 BIT(16)
+# define MCP25XXFD_IOCON_GPIO1 BIT(17)
+# define MCP25XXFD_IOCON_PM0 BIT(24)
+# define MCP25XXFD_IOCON_PM1 BIT(25)
+# define MCP25XXFD_IOCON_TXCANOD BIT(28)
+# define MCP25XXFD_IOCON_SOF BIT(29)
+# define MCP25XXFD_IOCON_INTOD BIT(30)
+#define MCP25XXFD_CRC MCP25XXFD_SFR_BASE(0x08)
+# define MCP25XXFD_CRC_MASK GENMASK(15, 0)
+# define MCP25XXFD_CRC_CRCERRIF BIT(16)
+# define MCP25XXFD_CRC_FERRIF BIT(17)
+# define MCP25XXFD_CRC_CRCERRIE BIT(24)
+# define MCP25XXFD_CRC_FERRIE BIT(25)
+#define MCP25XXFD_ECCCON MCP25XXFD_SFR_BASE(0x0C)
+# define MCP25XXFD_ECCCON_ECCEN BIT(0)
+# define MCP25XXFD_ECCCON_SECIE BIT(1)
+# define MCP25XXFD_ECCCON_DEDIE BIT(2)
+# define MCP25XXFD_ECCCON_PARITY_BITS 7
+# define MCP25XXFD_ECCCON_PARITY_SHIFT 8
+# define MCP25XXFD_ECCCON_PARITY_MASK \
+ GENMASK(MCP25XXFD_ECCCON_PARITY_SHIFT \
+ + MCP25XXFD_ECCCON_PARITY_BITS - 1, \
+ MCP25XXFD_ECCCON_PARITY_SHIFT)
+#define MCP25XXFD_ECCSTAT MCP25XXFD_SFR_BASE(0x10)
+# define MCP25XXFD_ECCSTAT_SECIF BIT(1)
+# define MCP25XXFD_ECCSTAT_DEDIF BIT(2)
+# define MCP25XXFD_ECCSTAT_ERRADDR_SHIFT 16
+# define MCP25XXFD_ECCSTAT_ERRADDR_MASK \
+ GENMASK(MCP25XXFD_ECCSTAT_ERRADDR_SHIFT + 11, \
+ MCP25XXFD_ECCSTAT_ERRADDR_SHIFT)
+
+#define MCP25XXFD_DEVID MCP25XXFD_SFR_BASE(0x14)
+# define MCP25XXFD_DEVID_REV_BITS 4
+# define MCP25XXFD_DEVID_REV_SHIFT 0
+# define MCP25XXFD_DEVID_REV_MASK \
+ GENMASK(MCP25XXFD_DEVID_REV_SHIFT + \
+ MCP25XXFD_DEVID_REV_BITS - 1, \
+ MCP25XXFD_DEVID_REV_SHIFT)
+# define MCP25XXFD_DEVID_ID_BITS 4
+# define MCP25XXFD_DEVID_ID_SHIFT 4
+# define MCP25XXFD_DEVID_ID_MASK \
+ GENMASK(MCP25XXFD_DEVID_ID_SHIFT + \
+ MCP25XXFD_DEVID_ID_BITS - 1, \
+ MCP25XXFD_DEVID_ID_SHIFT)
+
+/* CAN related register definitions of Controller CAN block */
+#define MCP25XXFD_CAN_SFR_BASE(x) (0x000 + (x))
+#define MCP25XXFD_CAN_CON \
+ MCP25XXFD_CAN_SFR_BASE(0x00)
+# define MCP25XXFD_CAN_CON_DNCNT_BITS 5
+# define MCP25XXFD_CAN_CON_DNCNT_SHIFT 0
+# define MCP25XXFD_CAN_CON_DNCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_CON_DNCNT_SHIFT + \
+ MCP25XXFD_CAN_CON_DNCNT_BITS - 1, \
+ MCP25XXFD_CAN_CON_DNCNT_SHIFT)
+# define MCP25XXFD_CAN_CON_ISOCRCEN BIT(5)
+# define MCP25XXFD_CAN_CON_PXEDIS BIT(6)
+# define MCP25XXFD_CAN_CON_WAKFIL BIT(8)
+# define MCP25XXFD_CAN_CON_WFT_BITS 2
+# define MCP25XXFD_CAN_CON_WFT_SHIFT 9
+# define MCP25XXFD_CAN_CON_WFT_MASK \
+ GENMASK(MCP25XXFD_CAN_CON_WFT_SHIFT + \
+ MCP25XXFD_CAN_CON_WFT_BITS - 1, \
+ MCP25XXFD_CAN_CON_WFT_SHIFT)
+# define MCP25XXFD_CAN_CON_BUSY BIT(11)
+# define MCP25XXFD_CAN_CON_BRSDIS BIT(12)
+# define MCP25XXFD_CAN_CON_RTXAT BIT(16)
+# define MCP25XXFD_CAN_CON_ESIGM BIT(17)
+# define MCP25XXFD_CAN_CON_SERR2LOM BIT(18)
+# define MCP25XXFD_CAN_CON_STEF BIT(19)
+# define MCP25XXFD_CAN_CON_TXQEN BIT(20)
+# define MCP25XXFD_CAN_CON_OPMOD_BITS 3
+# define MCP25XXFD_CAN_CON_OPMOD_SHIFT 21
+# define MCP25XXFD_CAN_CON_OPMOD_MASK \
+ GENMASK(MCP25XXFD_CAN_CON_OPMOD_SHIFT + \
+ MCP25XXFD_CAN_CON_OPMOD_BITS - 1, \
+ MCP25XXFD_CAN_CON_OPMOD_SHIFT)
+# define MCP25XXFD_CAN_CON_REQOP_BITS 3
+# define MCP25XXFD_CAN_CON_REQOP_SHIFT 24
+# define MCP25XXFD_CAN_CON_REQOP_MASK \
+ GENMASK(MCP25XXFD_CAN_CON_REQOP_SHIFT + \
+ MCP25XXFD_CAN_CON_REQOP_BITS - 1, \
+ MCP25XXFD_CAN_CON_REQOP_SHIFT)
+# define MCP25XXFD_CAN_CON_MODE_MIXED 0
+# define MCP25XXFD_CAN_CON_MODE_SLEEP 1
+# define MCP25XXFD_CAN_CON_MODE_INT_LOOPBACK 2
+# define MCP25XXFD_CAN_CON_MODE_LISTENONLY 3
+# define MCP25XXFD_CAN_CON_MODE_CONFIG 4
+# define MCP25XXFD_CAN_CON_MODE_EXT_LOOPBACK 5
+# define MCP25XXFD_CAN_CON_MODE_CAN2_0 6
+# define MCP25XXFD_CAN_CON_MODE_RESTRICTED 7
+# define MCP25XXFD_CAN_CON_ABAT BIT(27)
+# define MCP25XXFD_CAN_CON_TXBWS_BITS 4
+# define MCP25XXFD_CAN_CON_TXBWS_SHIFT 28
+# define MCP25XXFD_CAN_CON_TXBWS_MASK \
+ GENMASK(MCP25XXFD_CAN_CON_TXBWS_SHIFT + \
+ MCP25XXFD_CAN_CON_TXBWS_BITS - 1, \
+ MCP25XXFD_CAN_CON_TXBWS_SHIFT)
+# define MCP25XXFD_CAN_CON_DEFAULT \
+ (MCP25XXFD_CAN_CON_ISOCRCEN | \
+ MCP25XXFD_CAN_CON_PXEDIS | \
+ MCP25XXFD_CAN_CON_WAKFIL | \
+ (3 << MCP25XXFD_CAN_CON_WFT_SHIFT) | \
+ MCP25XXFD_CAN_CON_STEF | \
+ MCP25XXFD_CAN_CON_TXQEN | \
+ (MCP25XXFD_CAN_CON_MODE_CONFIG << MCP25XXFD_CAN_CON_OPMOD_SHIFT) | \
+ (MCP25XXFD_CAN_CON_MODE_CONFIG << MCP25XXFD_CAN_CON_REQOP_SHIFT))
+# define MCP25XXFD_CAN_CON_DEFAULT_MASK \
+ (MCP25XXFD_CAN_CON_DNCNT_MASK | \
+ MCP25XXFD_CAN_CON_ISOCRCEN | \
+ MCP25XXFD_CAN_CON_PXEDIS | \
+ MCP25XXFD_CAN_CON_WAKFIL | \
+ MCP25XXFD_CAN_CON_WFT_MASK | \
+ MCP25XXFD_CAN_CON_BRSDIS | \
+ MCP25XXFD_CAN_CON_RTXAT | \
+ MCP25XXFD_CAN_CON_ESIGM | \
+ MCP25XXFD_CAN_CON_SERR2LOM | \
+ MCP25XXFD_CAN_CON_STEF | \
+ MCP25XXFD_CAN_CON_TXQEN | \
+ MCP25XXFD_CAN_CON_OPMOD_MASK | \
+ MCP25XXFD_CAN_CON_REQOP_MASK | \
+ MCP25XXFD_CAN_CON_ABAT | \
+ MCP25XXFD_CAN_CON_TXBWS_MASK)
+#define MCP25XXFD_CAN_NBTCFG MCP25XXFD_CAN_SFR_BASE(0x04)
+# define MCP25XXFD_CAN_NBTCFG_SJW_BITS 7
+# define MCP25XXFD_CAN_NBTCFG_SJW_SHIFT 0
+# define MCP25XXFD_CAN_NBTCFG_SJW_MASK \
+ GENMASK(MCP25XXFD_CAN_NBTCFG_SJW_SHIFT + \
+ MCP25XXFD_CAN_NBTCFG_SJW_BITS - 1, \
+ MCP25XXFD_CAN_NBTCFG_SJW_SHIFT)
+# define MCP25XXFD_CAN_NBTCFG_TSEG2_BITS 7
+# define MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT 8
+# define MCP25XXFD_CAN_NBTCFG_TSEG2_MASK \
+ GENMASK(MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT + \
+ MCP25XXFD_CAN_NBTCFG_TSEG2_BITS - 1, \
+ MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT)
+# define MCP25XXFD_CAN_NBTCFG_TSEG1_BITS 8
+# define MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT 16
+# define MCP25XXFD_CAN_NBTCFG_TSEG1_MASK \
+ GENMASK(MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT + \
+ MCP25XXFD_CAN_NBTCFG_TSEG1_BITS - 1, \
+ MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT)
+# define MCP25XXFD_CAN_NBTCFG_BRP_BITS 8
+# define MCP25XXFD_CAN_NBTCFG_BRP_SHIFT 24
+# define MCP25XXFD_CAN_NBTCFG_BRP_MASK \
+ GENMASK(MCP25XXFD_CAN_NBTCFG_BRP_SHIFT + \
+ MCP25XXFD_CAN_NBTCFG_BRP_BITS - 1, \
+ MCP25XXFD_CAN_NBTCFG_BRP_SHIFT)
+#define MCP25XXFD_CAN_DBTCFG MCP25XXFD_CAN_SFR_BASE(0x08)
+# define MCP25XXFD_CAN_DBTCFG_SJW_BITS 4
+# define MCP25XXFD_CAN_DBTCFG_SJW_SHIFT 0
+# define MCP25XXFD_CAN_DBTCFG_SJW_MASK \
+ GENMASK(MCP25XXFD_CAN_DBTCFG_SJW_SHIFT + \
+ MCP25XXFD_CAN_DBTCFG_SJW_BITS - 1, \
+ MCP25XXFD_CAN_DBTCFG_SJW_SHIFT)
+# define MCP25XXFD_CAN_DBTCFG_TSEG2_BITS 4
+# define MCP25XXFD_CAN_DBTCFG_TSEG2_SHIFT 8
+# define MCP25XXFD_CAN_DBTCFG_TSEG2_MASK \
+ GENMASK(MCP25XXFD_CAN_DBTCFG_TSEG2_SHIFT + \
+ MCP25XXFD_CAN_DBTCFG_TSEG2_BITS - 1, \
+ MCP25XXFD_CAN_DBTCFG_TSEG2_SHIFT)
+# define MCP25XXFD_CAN_DBTCFG_TSEG1_BITS 5
+# define MCP25XXFD_CAN_DBTCFG_TSEG1_SHIFT 16
+# define MCP25XXFD_CAN_DBTCFG_TSEG1_MASK \
+ GENMASK(MCP25XXFD_CAN_DBTCFG_TSEG1_SHIFT + \
+ MCP25XXFD_CAN_DBTCFG_TSEG1_BITS - 1, \
+ MCP25XXFD_CAN_DBTCFG_TSEG1_SHIFT)
+# define MCP25XXFD_CAN_DBTCFG_BRP_BITS 8
+# define MCP25XXFD_CAN_DBTCFG_BRP_SHIFT 24
+# define MCP25XXFD_CAN_DBTCFG_BRP_MASK \
+ GENMASK(MCP25XXFD_CAN_DBTCFG_BRP_SHIFT + \
+ MCP25XXFD_CAN_DBTCFG_BRP_BITS - 1, \
+ MCP25XXFD_CAN_DBTCFG_BRP_SHIFT)
+#define MCP25XXFD_CAN_TDC MCP25XXFD_CAN_SFR_BASE(0x0C)
+# define MCP25XXFD_CAN_TDC_TDCV_BITS 6
+# define MCP25XXFD_CAN_TDC_TDCV_SHIFT 0
+# define MCP25XXFD_CAN_TDC_TDCV_MASK \
+ GENMASK(MCP25XXFD_CAN_TDC_TDCV_SHIFT + \
+ MCP25XXFD_CAN_TDC_TDCV_BITS - 1, \
+ MCP25XXFD_CAN_TDC_TDCV_SHIFT)
+# define MCP25XXFD_CAN_TDC_TDCO_BITS 7
+# define MCP25XXFD_CAN_TDC_TDCO_SHIFT 8
+# define MCP25XXFD_CAN_TDC_TDCO_MASK \
+ GENMASK(MCP25XXFD_CAN_TDC_TDCO_SHIFT + \
+ MCP25XXFD_CAN_TDC_TDCO_BITS - 1, \
+ MCP25XXFD_CAN_TDC_TDCO_SHIFT)
+# define MCP25XXFD_CAN_TDC_TDCMOD_BITS 2
+# define MCP25XXFD_CAN_TDC_TDCMOD_SHIFT 16
+# define MCP25XXFD_CAN_TDC_TDCMOD_MASK \
+ GENMASK(MCP25XXFD_CAN_TDC_TDCMOD_SHIFT + \
+ MCP25XXFD_CAN_TDC_TDCMOD_BITS - 1, \
+ MCP25XXFD_CAN_TDC_TDCMOD_SHIFT)
+# define MCP25XXFD_CAN_TDC_TDCMOD_DISABLED 0
+# define MCP25XXFD_CAN_TDC_TDCMOD_MANUAL 1
+# define MCP25XXFD_CAN_TDC_TDCMOD_AUTO 2
+# define MCP25XXFD_CAN_TDC_SID11EN BIT(24)
+# define MCP25XXFD_CAN_TDC_EDGFLTEN BIT(25)
+#define MCP25XXFD_CAN_TBC MCP25XXFD_CAN_SFR_BASE(0x10)
+#define MCP25XXFD_CAN_TSCON MCP25XXFD_CAN_SFR_BASE(0x14)
+# define MCP25XXFD_CAN_TSCON_TBCPRE_BITS 10
+# define MCP25XXFD_CAN_TSCON_TBCPRE_SHIFT 0
+# define MCP25XXFD_CAN_TSCON_TBCPRE_MASK \
+ GENMASK(MCP25XXFD_CAN_TSCON_TBCPRE_SHIFT + \
+ MCP25XXFD_CAN_TSCON_TBCPRE_BITS - 1, \
+ MCP25XXFD_CAN_TSCON_TBCPRE_SHIFT)
+# define MCP25XXFD_CAN_TSCON_TBCEN BIT(16)
+# define MCP25XXFD_CAN_TSCON_TSEOF BIT(17)
+# define MCP25XXFD_CAN_TSCON_TSRES BIT(18)
+#define MCP25XXFD_CAN_VEC MCP25XXFD_CAN_SFR_BASE(0x18)
+# define MCP25XXFD_CAN_VEC_ICODE_BITS 7
+# define MCP25XXFD_CAN_VEC_ICODE_SHIFT 0
+# define MCP25XXFD_CAN_VEC_ICODE_MASK \
+ GENMASK(MCP25XXFD_CAN_VEC_ICODE_SHIFT + \
+ MCP25XXFD_CAN_VEC_ICODE_BITS - 1, \
+ MCP25XXFD_CAN_VEC_ICODE_SHIFT)
+# define MCP25XXFD_CAN_VEC_FILHIT_BITS 5
+# define MCP25XXFD_CAN_VEC_FILHIT_SHIFT 8
+# define MCP25XXFD_CAN_VEC_FILHIT_MASK \
+ GENMASK(MCP25XXFD_CAN_VEC_FILHIT_SHIFT + \
+ MCP25XXFD_CAN_VEC_FILHIT_BITS - 1, \
+ MCP25XXFD_CAN_VEC_FILHIT_SHIFT)
+# define MCP25XXFD_CAN_VEC_TXCODE_BITS 7
+# define MCP25XXFD_CAN_VEC_TXCODE_SHIFT 16
+# define MCP25XXFD_CAN_VEC_TXCODE_MASK \
+ GENMASK(MCP25XXFD_CAN_VEC_TXCODE_SHIFT + \
+ MCP25XXFD_CAN_VEC_TXCODE_BITS - 1, \
+ MCP25XXFD_CAN_VEC_TXCODE_SHIFT)
+# define MCP25XXFD_CAN_VEC_RXCODE_BITS 7
+# define MCP25XXFD_CAN_VEC_RXCODE_SHIFT 24
+# define MCP25XXFD_CAN_VEC_RXCODE_MASK \
+ GENMASK(MCP25XXFD_CAN_VEC_RXCODE_SHIFT + \
+ MCP25XXFD_CAN_VEC_RXCODE_BITS - 1, \
+ MCP25XXFD_CAN_VEC_RXCODE_SHIFT)
+#define MCP25XXFD_CAN_INT MCP25XXFD_CAN_SFR_BASE(0x1C)
+# define MCP25XXFD_CAN_INT_IF_SHIFT 0
+# define MCP25XXFD_CAN_INT_TXIF BIT(0)
+# define MCP25XXFD_CAN_INT_RXIF BIT(1)
+# define MCP25XXFD_CAN_INT_TBCIF BIT(2)
+# define MCP25XXFD_CAN_INT_MODIF BIT(3)
+# define MCP25XXFD_CAN_INT_TEFIF BIT(4)
+# define MCP25XXFD_CAN_INT_ECCIF BIT(8)
+# define MCP25XXFD_CAN_INT_SPICRCIF BIT(9)
+# define MCP25XXFD_CAN_INT_TXATIF BIT(10)
+# define MCP25XXFD_CAN_INT_RXOVIF BIT(11)
+# define MCP25XXFD_CAN_INT_SERRIF BIT(12)
+# define MCP25XXFD_CAN_INT_CERRIF BIT(13)
+# define MCP25XXFD_CAN_INT_WAKIF BIT(14)
+# define MCP25XXFD_CAN_INT_IVMIF BIT(15)
+# define MCP25XXFD_CAN_INT_IF_MASK \
+ (MCP25XXFD_CAN_INT_TXIF | \
+ MCP25XXFD_CAN_INT_RXIF | \
+ MCP25XXFD_CAN_INT_TBCIF | \
+ MCP25XXFD_CAN_INT_MODIF | \
+ MCP25XXFD_CAN_INT_TEFIF | \
+ MCP25XXFD_CAN_INT_ECCIF | \
+ MCP25XXFD_CAN_INT_SPICRCIF | \
+ MCP25XXFD_CAN_INT_TXATIF | \
+ MCP25XXFD_CAN_INT_RXOVIF | \
+ MCP25XXFD_CAN_INT_CERRIF | \
+ MCP25XXFD_CAN_INT_SERRIF | \
+ MCP25XXFD_CAN_INT_WAKIF | \
+ MCP25XXFD_CAN_INT_IVMIF)
+# define MCP25XXFD_CAN_INT_IF_CLEAR_MASK \
+ (MCP25XXFD_CAN_INT_TBCIF | \
+ MCP25XXFD_CAN_INT_MODIF | \
+ MCP25XXFD_CAN_INT_CERRIF | \
+ MCP25XXFD_CAN_INT_SERRIF | \
+ MCP25XXFD_CAN_INT_WAKIF | \
+ MCP25XXFD_CAN_INT_IVMIF)
+# define MCP25XXFD_CAN_INT_IE_SHIFT 16
+# define MCP25XXFD_CAN_INT_TXIE \
+ (MCP25XXFD_CAN_INT_TXIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_RXIE \
+ (MCP25XXFD_CAN_INT_RXIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_TBCIE \
+ (MCP25XXFD_CAN_INT_TBCIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_MODIE \
+ (MCP25XXFD_CAN_INT_MODIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_TEFIE \
+ (MCP25XXFD_CAN_INT_TEFIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_ECCIE \
+ (MCP25XXFD_CAN_INT_ECCIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_SPICRCIE \
+ (MCP25XXFD_CAN_INT_SPICRCIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_TXATIE \
+ (MCP25XXFD_CAN_INT_TXATIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_RXOVIE \
+ (MCP25XXFD_CAN_INT_RXOVIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_CERRIE \
+ (MCP25XXFD_CAN_INT_CERRIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_SERRIE \
+ (MCP25XXFD_CAN_INT_SERRIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_WAKIE \
+ (MCP25XXFD_CAN_INT_WAKIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_IVMIE \
+ (MCP25XXFD_CAN_INT_IVMIF << MCP25XXFD_CAN_INT_IE_SHIFT)
+# define MCP25XXFD_CAN_INT_IE_MASK \
+ (MCP25XXFD_CAN_INT_TXIE | \
+ MCP25XXFD_CAN_INT_RXIE | \
+ MCP25XXFD_CAN_INT_TBCIE | \
+ MCP25XXFD_CAN_INT_MODIE | \
+ MCP25XXFD_CAN_INT_TEFIE | \
+ MCP25XXFD_CAN_INT_ECCIE | \
+ MCP25XXFD_CAN_INT_SPICRCIE | \
+ MCP25XXFD_CAN_INT_TXATIE | \
+ MCP25XXFD_CAN_INT_RXOVIE | \
+ MCP25XXFD_CAN_INT_CERRIE | \
+ MCP25XXFD_CAN_INT_SERRIE | \
+ MCP25XXFD_CAN_INT_WAKIE | \
+ MCP25XXFD_CAN_INT_IVMIE)
+#define MCP25XXFD_CAN_RXIF MCP25XXFD_CAN_SFR_BASE(0x20)
+#define MCP25XXFD_CAN_TXIF MCP25XXFD_CAN_SFR_BASE(0x24)
+#define MCP25XXFD_CAN_RXOVIF MCP25XXFD_CAN_SFR_BASE(0x28)
+#define MCP25XXFD_CAN_TXATIF MCP25XXFD_CAN_SFR_BASE(0x2C)
+#define MCP25XXFD_CAN_TXREQ MCP25XXFD_CAN_SFR_BASE(0x30)
+#define MCP25XXFD_CAN_TREC MCP25XXFD_CAN_SFR_BASE(0x34)
+# define MCP25XXFD_CAN_TREC_REC_BITS 8
+# define MCP25XXFD_CAN_TREC_REC_SHIFT 0
+# define MCP25XXFD_CAN_TREC_REC_MASK \
+ GENMASK(MCP25XXFD_CAN_TREC_REC_SHIFT + \
+ MCP25XXFD_CAN_TREC_REC_BITS - 1, \
+ MCP25XXFD_CAN_TREC_REC_SHIFT)
+# define MCP25XXFD_CAN_TREC_TEC_BITS 8
+# define MCP25XXFD_CAN_TREC_TEC_SHIFT 8
+# define MCP25XXFD_CAN_TREC_TEC_MASK \
+ GENMASK(MCP25XXFD_CAN_TREC_TEC_SHIFT + \
+ MCP25XXFD_CAN_TREC_TEC_BITS - 1, \
+ MCP25XXFD_CAN_TREC_TEC_SHIFT)
+# define MCP25XXFD_CAN_TREC_EWARN BIT(16)
+# define MCP25XXFD_CAN_TREC_RXWARN BIT(17)
+# define MCP25XXFD_CAN_TREC_TXWARN BIT(18)
+# define MCP25XXFD_CAN_TREC_RXBP BIT(19)
+# define MCP25XXFD_CAN_TREC_TXBP BIT(20)
+# define MCP25XXFD_CAN_TREC_TXBO BIT(21)
+#define MCP25XXFD_CAN_BDIAG0 MCP25XXFD_CAN_SFR_BASE(0x38)
+# define MCP25XXFD_CAN_BDIAG0_NRERRCNT_BITS 8
+# define MCP25XXFD_CAN_BDIAG0_NRERRCNT_SHIFT 0
+# define MCP25XXFD_CAN_BDIAG0_NRERRCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_BDIAG0_NRERRCNT_SHIFT + \
+ MCP25XXFD_CAN_BDIAG0_NRERRCNT_BITS - 1, \
+ MCP25XXFD_CAN_BDIAG0_NRERRCNT_SHIFT)
+# define MCP25XXFD_CAN_BDIAG0_NTERRCNT_BITS 8
+# define MCP25XXFD_CAN_BDIAG0_NTERRCNT_SHIFT 8
+# define MCP25XXFD_CAN_BDIAG0_NTERRCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_BDIAG0_NTERRCNT_SHIFT + \
+ MCP25XXFD_CAN_BDIAG0_NTERRCNT_BITS - 1, \
+ MCP25XXFD_CAN_BDIAG0_NTERRCNT_SHIFT)
+# define MCP25XXFD_CAN_BDIAG0_DRERRCNT_BITS 8
+# define MCP25XXFD_CAN_BDIAG0_DRERRCNT_SHIFT 16
+# define MCP25XXFD_CAN_BDIAG0_DRERRCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_BDIAG0_DRERRCNT_SHIFT + \
+ MCP25XXFD_CAN_BDIAG0_DRERRCNT_BITS - 1, \
+ MCP25XXFD_CAN_BDIAG0_DRERRCNT_SHIFT)
+# define MCP25XXFD_CAN_BDIAG0_DTERRCNT_BITS 8
+# define MCP25XXFD_CAN_BDIAG0_DTERRCNT_SHIFT 24
+# define MCP25XXFD_CAN_BDIAG0_DTERRCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_BDIAG0_DTERRCNT_SHIFT + \
+ MCP25XXFD_CAN_BDIAG0_DTERRCNT_BITS - 1, \
+ MCP25XXFD_CAN_BDIAG0_DTERRCNT_SHIFT)
+#define MCP25XXFD_CAN_BDIAG1 MCP25XXFD_CAN_SFR_BASE(0x3C)
+# define MCP25XXFD_CAN_BDIAG1_EFMSGCNT_BITS 16
+# define MCP25XXFD_CAN_BDIAG1_EFMSGCNT_SHIFT 0
+# define MCP25XXFD_CAN_BDIAG1_EFMSGCNT_MASK \
+ GENMASK(MCP25XXFD_CAN_BDIAG1_EFMSGCNT_SHIFT + \
+ MCP25XXFD_CAN_BDIAG1_EFMSGCNT_BITS - 1, \
+ MCP25XXFD_CAN_BDIAG1_EFMSGCNT_SHIFT)
+# define MCP25XXFD_CAN_BDIAG1_NBIT0ERR BIT(16)
+# define MCP25XXFD_CAN_BDIAG1_NBIT1ERR BIT(17)
+# define MCP25XXFD_CAN_BDIAG1_NACKERR BIT(18)
+# define MCP25XXFD_CAN_BDIAG1_NFORMERR BIT(19)
+# define MCP25XXFD_CAN_BDIAG1_NSTUFERR BIT(20)
+# define MCP25XXFD_CAN_BDIAG1_NCRCERR BIT(21)
+# define MCP25XXFD_CAN_BDIAG1_TXBOERR BIT(23)
+# define MCP25XXFD_CAN_BDIAG1_DBIT0ERR BIT(24)
+# define MCP25XXFD_CAN_BDIAG1_DBIT1ERR BIT(25)
+# define MCP25XXFD_CAN_BDIAG1_DFORMERR BIT(27)
+# define MCP25XXFD_CAN_BDIAG1_DSTUFERR BIT(28)
+# define MCP25XXFD_CAN_BDIAG1_DCRCERR BIT(29)
+# define MCP25XXFD_CAN_BDIAG1_ESI BIT(30)
+# define MCP25XXFD_CAN_BDIAG1_DLCMM BIT(31)
+#define MCP25XXFD_CAN_TEFCON MCP25XXFD_CAN_SFR_BASE(0x40)
+# define MCP25XXFD_CAN_TEFCON_TEFNEIE BIT(0)
+# define MCP25XXFD_CAN_TEFCON_TEFHIE BIT(1)
+# define MCP25XXFD_CAN_TEFCON_TEFFIE BIT(2)
+# define MCP25XXFD_CAN_TEFCON_TEFOVIE BIT(3)
+# define MCP25XXFD_CAN_TEFCON_TEFTSEN BIT(5)
+# define MCP25XXFD_CAN_TEFCON_UINC BIT(8)
+# define MCP25XXFD_CAN_TEFCON_FRESET BIT(10)
+# define MCP25XXFD_CAN_TEFCON_FSIZE_BITS 5
+# define MCP25XXFD_CAN_TEFCON_FSIZE_SHIFT 24
+# define MCP25XXFD_CAN_TEFCON_FSIZE_MASK \
+ GENMASK(MCP25XXFD_CAN_TEFCON_FSIZE_SHIFT + \
+ MCP25XXFD_CAN_TEFCON_FSIZE_BITS - 1, \
+ MCP25XXFD_CAN_TEFCON_FSIZE_SHIFT)
+#define MCP25XXFD_CAN_TEFSTA MCP25XXFD_CAN_SFR_BASE(0x44)
+# define MCP25XXFD_CAN_TEFSTA_TEFNEIF BIT(0)
+# define MCP25XXFD_CAN_TEFSTA_TEFHIF BIT(1)
+# define MCP25XXFD_CAN_TEFSTA_TEFFIF BIT(2)
+# define MCP25XXFD_CAN_TEFSTA_TEFOVIF BIT(3)
+#define MCP25XXFD_CAN_TEFUA MCP25XXFD_CAN_SFR_BASE(0x48)
+#define MCP25XXFD_CAN_RESERVED MCP25XXFD_CAN_SFR_BASE(0x4C)
+#define MCP25XXFD_CAN_TXQCON MCP25XXFD_CAN_SFR_BASE(0x50)
+# define MCP25XXFD_CAN_TXQCON_TXQNIE BIT(0)
+# define MCP25XXFD_CAN_TXQCON_TXQEIE BIT(2)
+# define MCP25XXFD_CAN_TXQCON_TXATIE BIT(4)
+# define MCP25XXFD_CAN_TXQCON_TXEN BIT(7)
+# define MCP25XXFD_CAN_TXQCON_UINC BIT(8)
+# define MCP25XXFD_CAN_TXQCON_TXREQ BIT(9)
+# define MCP25XXFD_CAN_TXQCON_FRESET BIT(10)
+# define MCP25XXFD_CAN_TXQCON_TXPRI_BITS 5
+# define MCP25XXFD_CAN_TXQCON_TXPRI_SHIFT 16
+# define MCP25XXFD_CAN_TXQCON_TXPRI_MASK \
+ GENMASK(MCP25XXFD_CAN_TXQCON_TXPRI_SHIFT + \
+ MCP25XXFD_CAN_TXQCON_TXPRI_BITS - 1, \
+ MCP25XXFD_CAN_TXQCON_TXPRI_SHIFT)
+# define MCP25XXFD_CAN_TXQCON_TXAT_BITS 2
+# define MCP25XXFD_CAN_TXQCON_TXAT_SHIFT 21
+# define MCP25XXFD_CAN_TXQCON_TXAT_MASK \
+ GENMASK(MCP25XXFD_CAN_TXQCON_TXAT_SHIFT + \
+ #MCP25XXFD_CAN_TXQCON_TXAT_BITS - 1, \
+ MCP25XXFD_CAN_TXQCON_TXAT_SHIFT)
+# define MCP25XXFD_CAN_TXQCON_FSIZE_BITS 5
+# define MCP25XXFD_CAN_TXQCON_FSIZE_SHIFT 24
+# define MCP25XXFD_CAN_TXQCON_FSIZE_MASK \
+ GENMASK(MCP25XXFD_CAN_TXQCON_FSIZE_SHIFT + \
+ MCP25XXFD_CAN_TXQCON_FSIZE_BITS - 1, \
+ MCP25XXFD_CAN_TXQCON_FSIZE_SHIFT)
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_BITS 3
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_SHIFT 29
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_MASK \
+ GENMASK(MCP25XXFD_CAN_TXQCON_PLSIZE_SHIFT + \
+ MCP25XXFD_CAN_TXQCON_PLSIZE_BITS - 1, \
+ MCP25XXFD_CAN_TXQCON_PLSIZE_SHIFT)
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_8 0
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_12 1
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_16 2
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_20 3
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_24 4
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_32 5
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_48 6
+# define MCP25XXFD_CAN_TXQCON_PLSIZE_64 7
+
+#define MCP25XXFD_CAN_TXQSTA MCP25XXFD_CAN_SFR_BASE(0x54)
+# define MCP25XXFD_CAN_TXQSTA_TXQNIF BIT(0)
+# define MCP25XXFD_CAN_TXQSTA_TXQEIF BIT(2)
+# define MCP25XXFD_CAN_TXQSTA_TXATIF BIT(4)
+# define MCP25XXFD_CAN_TXQSTA_TXERR BIT(5)
+# define MCP25XXFD_CAN_TXQSTA_TXLARB BIT(6)
+# define MCP25XXFD_CAN_TXQSTA_TXABT BIT(7)
+# define MCP25XXFD_CAN_TXQSTA_TXQCI_BITS 5
+# define MCP25XXFD_CAN_TXQSTA_TXQCI_SHIFT 8
+# define MCP25XXFD_CAN_TXQSTA_TXQCI_MASK \
+ GENMASK(MCP25XXFD_CAN_TXQSTA_TXQCI_SHIFT + \
+ MCP25XXFD_CAN_TXQSTA_TXQCI_BITS - 1, \
+ MCP25XXFD_CAN_TXQSTA_TXQCI_SHIFT)
+
+#define MCP25XXFD_CAN_TXQUA MCP25XXFD_CAN_SFR_BASE(0x58)
+#define MCP25XXFD_CAN_FIFOCON(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x5C + 12 * ((x) - 1))
+#define MCP25XXFD_CAN_FIFOCON_TFNRFNIE BIT(0)
+#define MCP25XXFD_CAN_FIFOCON_TFHRFHIE BIT(1)
+#define MCP25XXFD_CAN_FIFOCON_TFERFFIE BIT(2)
+#define MCP25XXFD_CAN_FIFOCON_RXOVIE BIT(3)
+#define MCP25XXFD_CAN_FIFOCON_TXATIE BIT(4)
+#define MCP25XXFD_CAN_FIFOCON_RXTSEN BIT(5)
+#define MCP25XXFD_CAN_FIFOCON_RTREN BIT(6)
+#define MCP25XXFD_CAN_FIFOCON_TXEN BIT(7)
+#define MCP25XXFD_CAN_FIFOCON_UINC BIT(8)
+#define MCP25XXFD_CAN_FIFOCON_TXREQ BIT(9)
+#define MCP25XXFD_CAN_FIFOCON_FRESET BIT(10)
+# define MCP25XXFD_CAN_FIFOCON_TXPRI_BITS 5
+# define MCP25XXFD_CAN_FIFOCON_TXPRI_SHIFT 16
+# define MCP25XXFD_CAN_FIFOCON_TXPRI_MASK \
+ GENMASK(MCP25XXFD_CAN_FIFOCON_TXPRI_SHIFT + \
+ MCP25XXFD_CAN_FIFOCON_TXPRI_BITS - 1, \
+ MCP25XXFD_CAN_FIFOCON_TXPRI_SHIFT)
+# define MCP25XXFD_CAN_FIFOCON_TXAT_BITS 2
+# define MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT 21
+# define MCP25XXFD_CAN_FIFOCON_TXAT_MASK \
+ GENMASK(MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT + \
+ MCP25XXFD_CAN_FIFOCON_TXAT_BITS - 1, \
+ MCP25XXFD_CAN_FIFOCON_TXAT_SHIFT)
+# define MCP25XXFD_CAN_FIFOCON_TXAT_ONE_SHOT 0
+# define MCP25XXFD_CAN_FIFOCON_TXAT_THREE_SHOT 1
+# define MCP25XXFD_CAN_FIFOCON_TXAT_UNLIMITED 2
+# define MCP25XXFD_CAN_FIFOCON_FSIZE_BITS 5
+# define MCP25XXFD_CAN_FIFOCON_FSIZE_SHIFT 24
+# define MCP25XXFD_CAN_FIFOCON_FSIZE_MASK \
+ GENMASK(MCP25XXFD_CAN_FIFOCON_FSIZE_SHIFT + \
+ MCP25XXFD_CAN_FIFOCON_FSIZE_BITS - 1, \
+ MCP25XXFD_CAN_FIFOCON_FSIZE_SHIFT)
+# define MCP25XXFD_CAN_FIFOCON_PLSIZE_BITS 3
+# define MCP25XXFD_CAN_FIFOCON_PLSIZE_SHIFT 29
+# define MCP25XXFD_CAN_FIFOCON_PLSIZE_MASK \
+ GENMASK(MCP25XXFD_CAN_FIFOCON_PLSIZE_SHIFT + \
+ MCP25XXFD_CAN_FIFOCON_PLSIZE_BITS - 1, \
+ MCP25XXFD_CAN_FIFOCON_PLSIZE_SHIFT)
+#define MCP25XXFD_CAN_FIFOSTA(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x60 + 12 * ((x) - 1))
+# define MCP25XXFD_CAN_FIFOSTA_TFNRFNIF BIT(0)
+# define MCP25XXFD_CAN_FIFOSTA_TFHRFHIF BIT(1)
+# define MCP25XXFD_CAN_FIFOSTA_TFERFFIF BIT(2)
+# define MCP25XXFD_CAN_FIFOSTA_RXOVIF BIT(3)
+# define MCP25XXFD_CAN_FIFOSTA_TXATIF BIT(4)
+# define MCP25XXFD_CAN_FIFOSTA_TXERR BIT(5)
+# define MCP25XXFD_CAN_FIFOSTA_TXLARB BIT(6)
+# define MCP25XXFD_CAN_FIFOSTA_TXABT BIT(7)
+# define MCP25XXFD_CAN_FIFOSTA_FIFOCI_BITS 5
+# define MCP25XXFD_CAN_FIFOSTA_FIFOCI_SHIFT 8
+# define MCP25XXFD_CAN_FIFOSTA_FIFOCI_MASK \
+ GENMASK(MCP25XXFD_CAN_FIFOSTA_FIFOCI_SHIFT + \
+ MCP25XXFD_CAN_FIFOSTA_FIFOCI_BITS - 1, \
+ MCP25XXFD_CAN_FIFOSTA_FIFOCI_SHIFT)
+#define MCP25XXFD_CAN_FIFOUA(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x64 + 12 * ((x) - 1))
+#define MCP25XXFD_CAN_FLTCON(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x1D0 + (x))
+# define MCP25XXFD_CAN_FLTCON_SHIFT(x) (((x) & 3) * 8)
+# define MCP25XXFD_CAN_FLTCON_BITS(x) MCP25XXFD_CAN_FLTCON_BITS_
+# define MCP25XXFD_CAN_FLTCON_BITS_ 5
+ /* avoid macro reuse warning, so do not use GENMASK as above */
+# define MCP25XXFD_CAN_FLTCON_MASK(x) \
+ (GENMASK(MCP25XXFD_CAN_FLTCON_BITS_ - 1, 0) << \
+ MCP25XXFD_CAN_FLTCON_SHIFT(x))
+# define MCP25XXFD_CAN_FLTCON_FLTEN(x) \
+ BIT(7 + MCP25XXFD_CAN_FLTCON_SHIFT(x))
+#define MCP25XXFD_CAN_FLTOBJ(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x1F0 + 8 * (x))
+# define MCP25XXFD_CAN_FLTOBJ_SID_BITS 11
+# define MCP25XXFD_CAN_FLTOBJ_SID_SHIFT 0
+# define MCP25XXFD_CAN_FLTOBJ_SID_MASK \
+ GENMASK(MCP25XXFD_CAN_FLTOBJ_SID_SHIFT + \
+ MCP25XXFD_CAN_FLTOBJ_SID_BITS - 1, \
+ MCP25XXFD_CAN_FLTOBJ_SID_SHIFT)
+# define MCP25XXFD_CAN_FLTOBJ_EID_BITS 18
+# define MCP25XXFD_CAN_FLTOBJ_EID_SHIFT 11
+# define MCP25XXFD_CAN_FLTOBJ_EID_MASK \
+ GENMASK(MCP25XXFD_CAN_FLTOBJ_EID_SHIFT + \
+ MCP25XXFD_CAN_FLTOBJ_EID_BITS - 1, \
+ MCP25XXFD_CAN_FLTOBJ_EID_SHIFT)
+# define MCP25XXFD_CAN_FLTOBJ_SID11 BIT(29)
+# define MCP25XXFD_CAN_FLTOBJ_EXIDE BIT(30)
+#define MCP25XXFD_CAN_FLTMASK(x) \
+ MCP25XXFD_CAN_SFR_BASE(0x1F4 + 8 * (x))
+# define MCP25XXFD_CAN_MASK_MSID_BITS 11
+# define MCP25XXFD_CAN_MASK_MSID_SHIFT 0
+# define MCP25XXFD_CAN_MASK_MSID_MASK \
+ GENMASK(MCP25XXFD_CAN_MASK_MSID_SHIFT + \
+ MCP25XXFD_CAN_MASK_MSID_BITS - 1, \
+ MCP25XXFD_CAN_MASK_MSID_SHIFT)
+# define MCP25XXFD_CAN_MASK_MEID_BITS 18
+# define MCP25XXFD_CAN_MASK_MEID_SHIFT 11
+# define MCP25XXFD_CAN_MASK_MEID_MASK \
+ GENMASK(MCP25XXFD_CAN_MASK_MEID_SHIFT + \
+ MCP25XXFD_CAN_MASK_MEID_BITS - 1, \
+ MCP25XXFD_CAN_MASK_MEID_SHIFT)
+# define MCP25XXFD_CAN_MASK_MSID11 BIT(29)
+# define MCP25XXFD_CAN_MASK_MIDE BIT(30)
+
+/* the FIFO Objects in SRAM */
+#define MCP25XXFD_SRAM_SIZE 2048
+#define MCP25XXFD_SRAM_ADDR(x) (0x400 + (x))
+
+/* memory structure in sram for tx fifos */
+struct mcp25xxfd_can_obj_tx {
+ u32 id;
+ u32 flags;
+ u8 data[];
+};
+
+/* memory structure in sram for rx fifos */
+struct mcp25xxfd_can_obj_rx {
+ u32 id;
+ u32 flags;
+ u32 ts;
+ u8 data[];
+};
+
+/* memory structure in sram for tef fifos */
+struct mcp25xxfd_can_obj_tef {
+ u32 id;
+ u32 flags;
+ u32 ts;
+};
+
+#define MCP25XXFD_CAN_OBJ_ID_SID_BITS 11
+#define MCP25XXFD_CAN_OBJ_ID_SID_SHIFT 0
+#define MCP25XXFD_CAN_OBJ_ID_SID_MASK \
+ GENMASK(MCP25XXFD_CAN_OBJ_ID_SID_SHIFT + \
+ MCP25XXFD_CAN_OBJ_ID_SID_BITS - 1, \
+ MCP25XXFD_CAN_OBJ_ID_SID_SHIFT)
+#define MCP25XXFD_CAN_OBJ_ID_EID_BITS 18
+#define MCP25XXFD_CAN_OBJ_ID_EID_SHIFT 11
+#define MCP25XXFD_CAN_OBJ_ID_EID_MASK \
+ GENMASK(MCP25XXFD_CAN_OBJ_ID_EID_SHIFT + \
+ MCP25XXFD_CAN_OBJ_ID_EID_BITS - 1, \
+ MCP25XXFD_CAN_OBJ_ID_EID_SHIFT)
+#define MCP25XXFD_CAN_OBJ_ID_SID_BIT11 BIT(29)
+
+#define MCP25XXFD_CAN_OBJ_FLAGS_DLC_BITS 4
+#define MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT 0
+#define MCP25XXFD_CAN_OBJ_FLAGS_DLC_MASK \
+ GENMASK(MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT + \
+ MCP25XXFD_CAN_OBJ_FLAGS_DLC_BITS - 1, \
+ MCP25XXFD_CAN_OBJ_FLAGS_DLC_SHIFT)
+#define MCP25XXFD_CAN_OBJ_FLAGS_IDE BIT(4)
+#define MCP25XXFD_CAN_OBJ_FLAGS_RTR BIT(5)
+#define MCP25XXFD_CAN_OBJ_FLAGS_BRS BIT(6)
+#define MCP25XXFD_CAN_OBJ_FLAGS_FDF BIT(7)
+#define MCP25XXFD_CAN_OBJ_FLAGS_ESI BIT(8)
+#define MCP25XXFD_CAN_OBJ_FLAGS_SEQ_BITS 7
+#define MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT 9
+#define MCP25XXFD_CAN_OBJ_FLAGS_SEQ_MASK \
+ GENMASK(MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT + \
+ MCP25XXFD_CAN_OBJ_FLAGS_SEQ_BITS - 1, \
+ MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT)
+/* the mcp2518 has an extended number of SEQ bits */
+#define MCP25XXFD_CAN_OBJ_FLAGS_SEQX_BITS 23
+#define MCP25XXFD_CAN_OBJ_FLAGS_SEQX_MASK \
+ GENMASK(MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT + \
+ MCP25XXFD_CAN_OBJ_FLAGS_SEQX_BITS - 1, \
+ MCP25XXFD_CAN_OBJ_FLAGS_SEQ_SHIFT)
+#define MCP25XXFD_CAN_OBJ_FLAGS_FILHIT_BITS 5
+#define MCP25XXFD_CAN_OBJ_FLAGS_FILHIT_SHIFT 11
+#define MCP25XXFD_CAN_OBJ_FLAGS_FILHIT_MASK \
+ GENMASK(MCP25XXFD_CAN_FLAGS_FILHIT_SHIFT + \
+ MCP25XXFD_CAN_FLAGS_FILHIT_BITS - 1, \
+ MCP25XXFD_CAN_FLAGS_FILHIT_SHIFT)
+
+/* custom status error */
+#define MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_SERR_RX BIT(0)
+#define MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_SERR_TX BIT(1)
+#define MCP25XXFD_CAN_ERR_DATA7_MCP25XXFD_ECC BIT(2)
+
+#endif /* __MCP25XXFD_REGS_H */
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 98751558e50f..ec163c6192db 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -387,8 +387,7 @@ struct bufdesc_ex {
#define FEC_ENET_TS_AVAIL ((uint)0x00010000)
#define FEC_ENET_TS_TIMER ((uint)0x00008000)
-#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
-#define FEC_NAPI_IMASK FEC_ENET_MII
+#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF)
#define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
#define FEC_ENET_ETHEREN ((uint)0x00000002)
@@ -491,6 +490,12 @@ struct fec_enet_stop_mode {
u8 req_bit;
};
+/* Some FEC hardware blocks need the MMFR cleared at setup time to avoid
+ * the generation of an MII event. This must be avoided in the older
+ * FEC blocks where it will stop MII events being generated.
+ */
+#define FEC_QUIRK_CLEAR_SETUP_MII (1 << 17)
+
struct bufdesc_prop {
int qid;
/* Address of Rx and Tx buffers */
@@ -576,7 +581,6 @@ struct fec_enet_private {
int link;
int full_duplex;
int speed;
- struct completion mdio_done;
int irq[FEC_IRQ_NUM];
bool bufdesc_ex;
int pause_flag;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index abee8441c491..1f349c121a88 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -36,6 +36,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
+#include <linux/iopoll.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <net/tso.h>
@@ -105,13 +106,14 @@ static struct platform_device_id fec_devtype[] = {
.name = "imx28-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
- FEC_QUIRK_HAS_FRREG,
+ FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "imx6q-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
- FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_PMQOS,
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_PMQOS |
+ FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "mvf600-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
@@ -121,14 +123,15 @@ static struct platform_device_id fec_devtype[] = {
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
- FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
+ FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "imx6ul-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
- FEC_QUIRK_HAS_COALESCE,
+ FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "imx8mq-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
@@ -136,7 +139,7 @@ static struct platform_device_id fec_devtype[] = {
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
- FEC_QUIRK_HAS_EEE,
+ FEC_QUIRK_HAS_EEE | FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "imx8qm-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
@@ -144,13 +147,14 @@ static struct platform_device_id fec_devtype[] = {
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
- FEC_QUIRK_DELAYED_CLKS_SUPPORT,
+ FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_CLEAR_SETUP_MII,
}, {
.name = "s32v234-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
- FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE,
+ FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+ FEC_QUIRK_CLEAR_SETUP_MII,
}, {
/* sentinel */
}
@@ -979,8 +983,8 @@ fec_restart(struct net_device *ndev)
writel((__force u32)cpu_to_be32(temp_mac[1]),
fep->hwp + FEC_ADDR_HIGH);
- /* Clear any outstanding interrupt. */
- writel(0xffffffff, fep->hwp + FEC_IEVENT);
+ /* Clear any outstanding interrupt, except MDIO. */
+ writel((0xffffffff & ~FEC_ENET_MII), fep->hwp + FEC_IEVENT);
fec_enet_bd_init(ndev);
@@ -1133,7 +1137,7 @@ fec_restart(struct net_device *ndev)
if (fep->link)
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
else
- writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(0, fep->hwp + FEC_IMASK);
/* Init the interrupt coalescing */
fec_enet_itr_coal_init(ndev);
@@ -1714,6 +1718,10 @@ fec_enet_interrupt(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE;
int_events = readl(fep->hwp + FEC_IEVENT);
+
+ /* Don't clear MDIO events, we poll for those */
+ int_events &= ~FEC_ENET_MII;
+
writel(int_events, fep->hwp + FEC_IEVENT);
fec_enet_collect_events(fep, int_events);
@@ -1721,16 +1729,12 @@ fec_enet_interrupt(int irq, void *dev_id)
ret = IRQ_HANDLED;
if (napi_schedule_prep(&fep->napi)) {
- /* Disable the NAPI interrupts */
- writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
+ /* Disable interrupts */
+ writel(0, fep->hwp + FEC_IMASK);
__napi_schedule(&fep->napi);
}
}
- if (int_events & FEC_ENET_MII) {
- ret = IRQ_HANDLED;
- complete(&fep->mdio_done);
- }
return ret;
}
@@ -1884,11 +1888,24 @@ static void fec_enet_adjust_link(struct net_device *ndev)
phy_print_status(phy_dev);
}
+static int fec_enet_mdio_wait(struct fec_enet_private *fep)
+{
+ uint ievent;
+ int ret;
+
+ ret = readl_poll_timeout_atomic(fep->hwp + FEC_IEVENT, ievent,
+ ievent & FEC_ENET_MII, 2, 30000);
+
+ if (!ret)
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
+
+ return ret;
+}
+
static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev;
- unsigned long time_left;
uint int_events;
int ret = 0, frame_start, frame_addr, frame_op;
bool is_c45 = !!(regnum & MII_ADDR_C45);
@@ -1897,8 +1914,6 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret < 0)
return ret;
- reinit_completion(&fep->mdio_done);
-
if (is_c45) {
frame_start = FEC_MMFR_ST_C45;
@@ -1910,11 +1925,9 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- time_left = wait_for_completion_timeout(&fep->mdio_done,
- usecs_to_jiffies(FEC_MII_TIMEOUT));
- if (time_left == 0) {
+ ret = fec_enet_mdio_wait(fep);
+ if (ret) {
netdev_err(fep->netdev, "MDIO address write timeout\n");
- ret = -ETIMEDOUT;
goto out;
}
@@ -1933,15 +1946,10 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- time_left = wait_for_completion_timeout(&fep->mdio_done,
- usecs_to_jiffies(FEC_MII_TIMEOUT));
- if (time_left == 0) {
- int_events = readl(fep->hwp + FEC_IEVENT);
- if (!(int_events & FEC_ENET_MII)) {
- netdev_err(fep->netdev, "MDIO read timeout\n");
- ret = -ETIMEDOUT;
- goto out;
- }
+ ret = fec_enet_mdio_wait(fep);
+ if (ret) {
+ netdev_err(fep->netdev, "MDIO read timeout\n");
+ goto out;
}
ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
@@ -1958,7 +1966,6 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
{
struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev;
- unsigned long time_left;
int ret, frame_start, frame_addr;
bool is_c45 = !!(regnum & MII_ADDR_C45);
@@ -1968,8 +1975,6 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
else
ret = 0;
- reinit_completion(&fep->mdio_done);
-
if (is_c45) {
frame_start = FEC_MMFR_ST_C45;
@@ -1981,11 +1986,9 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- time_left = wait_for_completion_timeout(&fep->mdio_done,
- usecs_to_jiffies(FEC_MII_TIMEOUT));
- if (time_left == 0) {
+ ret = fec_enet_mdio_wait(fep);
+ if (ret) {
netdev_err(fep->netdev, "MDIO address write timeout\n");
- ret = -ETIMEDOUT;
goto out;
}
} else {
@@ -2001,12 +2004,9 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- time_left = wait_for_completion_timeout(&fep->mdio_done,
- usecs_to_jiffies(FEC_MII_TIMEOUT));
- if (time_left == 0) {
+ ret = fec_enet_mdio_wait(fep);
+ if (ret)
netdev_err(fep->netdev, "MDIO write timeout\n");
- ret = -ETIMEDOUT;
- }
out:
pm_runtime_mark_last_busy(dev);
@@ -2173,6 +2173,8 @@ static int fec_enet_mii_probe(struct net_device *ndev)
fep->link = 0;
fep->full_duplex = 0;
+ phy_dev->mac_managed_pm = 1;
+
phy_attached_info(phy_dev);
return 0;
@@ -2250,8 +2252,23 @@ static int fec_enet_mii_init(struct platform_device *pdev)
fep->phy_speed = mii_speed << 1 | holdtime << 8;
+ if (fep->quirks & FEC_QUIRK_CLEAR_SETUP_MII) {
+ /* Clear MMFR to avoid to generate MII event by writing MSCR.
+ * MII event generation condition:
+ * - writing MSCR:
+ * - mmfr[31:0]_not_zero & mscr[7:0]_is_zero &
+ * mscr_reg_data_in[7:0] != 0
+ * - writing MMFR:
+ * - mscr[7:0]_not_zero
+ */
+ writel(0, fep->hwp + FEC_MII_DATA);
+ }
+
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+ /* Clear any pending transaction complete indication */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
+
fep->mii_bus = mdiobus_alloc();
if (fep->mii_bus == NULL) {
err = -ENOMEM;
@@ -3952,7 +3969,6 @@ fec_probe(struct platform_device *pdev)
else
fep->wake_irq = fep->irq[0];
- init_completion(&fep->mdio_done);
/* board only enable one mii bus in default */
if (!of_get_property(np, "fsl,mii-exclusive", NULL))
fep->quirks |= FEC_QUIRK_SINGLE_MDIO;
@@ -4084,8 +4100,10 @@ static int __maybe_unused fec_suspend(struct device *dev)
}
rtnl_unlock();
- if (fep->reg_phy && !(fep->wol_flag & FEC_WOL_FLAG_ENABLE))
+ if (fep->reg_phy && !(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
+ disable_irq(ndev->phydev->irq);
regulator_disable(fep->reg_phy);
+ }
/* SOC supply clock to phy, when clock is disabled, phy link down
* SOC control phy regulator, when regulator is disabled, phy link down
@@ -4107,6 +4125,7 @@ static int __maybe_unused fec_resume(struct device *dev)
ret = regulator_enable(fep->reg_phy);
if (ret)
return ret;
+ enable_irq(ndev->phydev->irq);
}
rtnl_lock();
@@ -4135,6 +4154,7 @@ static int __maybe_unused fec_resume(struct device *dev)
netif_device_attach(ndev);
netif_tx_unlock_bh(ndev);
napi_enable(&fep->napi);
+ phy_init_hw(ndev->phydev);
phy_start(ndev->phydev);
} else if (fep->mii_bus_share && !ndev->phydev) {
pinctrl_pm_select_default_state(&fep->pdev->dev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index f86d24af34c4..0ca403fff0c0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -19,6 +19,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/stmmac.h>
@@ -50,6 +51,7 @@ struct imx_priv_data {
struct clk *clk_tx;
struct clk *clk_mem;
struct regmap *intf_regmap;
+ struct regulator *regulator;
u32 intf_reg_off;
bool rmii_refclk_ext;
@@ -176,6 +178,14 @@ static int imx_dwmac_init(struct platform_device *pdev, void *priv)
goto intf_mode_failed;
}
+ if (dwmac->regulator) {
+ ret = regulator_enable(dwmac->regulator);
+ if (ret) {
+ dev_err(dwmac->dev, "fail to enable phy-supply\n");
+ goto intf_mode_failed;
+ }
+ }
+
return 0;
intf_mode_failed:
@@ -205,6 +215,13 @@ static void imx_dwmac_exit(struct platform_device *pdev, void *priv)
if (dwmac->clk_tx)
clk_disable_unprepare(dwmac->clk_tx);
clk_disable_unprepare(dwmac->clk_mem);
+
+ if (dwmac->regulator) {
+ ret = regulator_disable(dwmac->regulator);
+ if (ret)
+ dev_err(dwmac->dev, "fail to disable phy-supply\n");
+ }
+
pm_runtime_put(&pdev->dev);
}
@@ -280,6 +297,16 @@ imx_dwmac_parse_dt(struct imx_priv_data *dwmac, struct device *dev)
}
}
+ /* Optional regulator for PHY */
+ dwmac->regulator = devm_regulator_get_optional(dev, "phy");
+ if (IS_ERR(dwmac->regulator)) {
+ if (PTR_ERR(dwmac->regulator) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ }
+ dev_err(dev, "no regulator found\n");
+ dwmac->regulator = NULL;
+ }
+
return err;
}
@@ -315,7 +342,8 @@ static int imx_dwmac_probe(struct platform_device *pdev)
ret = imx_dwmac_parse_dt(dwmac, &pdev->dev);
if (ret) {
- dev_err(&pdev->dev, "failed to parse OF data\n");
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to parse OF data\n");
goto err_parse_dt;
}
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 18cc5e4280e8..e297be3449e6 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -705,6 +705,90 @@ static int ksz9131_of_load_skew_values(struct phy_device *phydev,
return phy_write_mmd(phydev, 2, reg, newval);
}
+#define KSZ9131RN_MMD_COMMON_CTRL_REG 2
+#define KSZ9131RN_RXC_DLL_CTRL 76
+#define KSZ9131RN_TXC_DLL_CTRL 77
+#define KSZ9131RN_DLL_CTRL_BYPASS BIT_MASK(12)
+#define KSZ9131RN_DLL_ENABLE_DELAY 0
+#define KSZ9131RN_DLL_DISABLE_DELAY BIT(12)
+
+static int ksz9131_config_rgmii_delay(struct phy_device *phydev)
+{
+ u16 rxcdll_val, txcdll_val;
+ int new, ret;
+
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ rxcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+ txcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ rxcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+ txcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ rxcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+ txcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ rxcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+ txcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+ break;
+ default:
+ return 0;
+ }
+
+ ret = phy_read_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_RXC_DLL_CTRL);
+ if (ret < 0)
+ return ret;
+
+ new = (ret & ~KSZ9131RN_DLL_CTRL_BYPASS) | rxcdll_val;
+
+ if (new != ret) {
+ ret = phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_RXC_DLL_CTRL, new);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = phy_read_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_TXC_DLL_CTRL);
+ if (ret < 0)
+ return ret;
+
+ new = (ret & ~KSZ9131RN_DLL_CTRL_BYPASS) | txcdll_val;
+
+ if (new != ret) {
+ ret = phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_TXC_DLL_CTRL, new);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Silicon Errata DS80000693B
+ *
+ * When LEDs are configured in Individual Mode, LED1 is ON in a no-link
+ * condition. Workaround is to set register 0x1e, bit 9, this way LED1 behaves
+ * according to the datasheet (off if there is no link).
+ */
+static int ksz9131_led_errata(struct phy_device *phydev)
+{
+ int reg;
+
+ reg = phy_read_mmd(phydev, 2, 0);
+ if (reg < 0)
+ return reg;
+
+ if (!(reg & BIT(4)))
+ return 0;
+
+ return phy_set_bits(phydev, 0x1e, BIT(9));
+}
+
static int ksz9131_config_init(struct phy_device *phydev)
{
const struct device *dev = &phydev->mdio.dev;
@@ -731,6 +815,12 @@ static int ksz9131_config_init(struct phy_device *phydev)
if (!of_node)
return 0;
+ if (phy_interface_is_rgmii(phydev)) {
+ ret = ksz9131_config_rgmii_delay(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
ret = ksz9131_of_load_skew_values(phydev, of_node,
MII_KSZ9031RN_CLK_PAD_SKEW, 5,
clk_skews, 2);
@@ -755,6 +845,10 @@ static int ksz9131_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
+ ret = ksz9131_led_errata(phydev);
+ if (ret < 0)
+ return ret;
+
return 0;
}
@@ -1162,7 +1256,7 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings = kszphy_get_strings,
.get_stats = kszphy_get_stats,
- .suspend = genphy_suspend,
+ .suspend = kszphy_suspend,
.resume = kszphy_resume,
}, {
.phy_id = PHY_ID_KSZ8873MLL,
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 6c52ff8c0d2e..9e8cf64f0442 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -116,10 +116,15 @@ EXPORT_SYMBOL(phy_print_status);
*/
static int phy_clear_interrupt(struct phy_device *phydev)
{
- if (phydev->drv->ack_interrupt)
- return phydev->drv->ack_interrupt(phydev);
+ int ret = 0;
- return 0;
+ if (phydev->drv->ack_interrupt) {
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->ack_interrupt(phydev);
+ mutex_unlock(&phydev->lock);
+ }
+
+ return ret;
}
/**
@@ -761,6 +766,36 @@ static int phy_disable_interrupts(struct phy_device *phydev)
}
/**
+ * phy_did_interrupt - Checks if the PHY generated an interrupt
+ * @phydev: target phy_device struct
+ */
+static int phy_did_interrupt(struct phy_device *phydev)
+{
+ int ret;
+
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->did_interrupt(phydev);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+}
+
+/**
+ * phy_handle_interrupt - PHY specific interrupt handler
+ * @phydev: target phy_device struct
+ */
+static int phy_handle_interrupt(struct phy_device *phydev)
+{
+ int ret;
+
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->handle_interrupt(phydev);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+}
+
+/**
* phy_interrupt - PHY interrupt handler
* @irq: interrupt line
* @phy_dat: phy_device pointer
@@ -771,11 +806,11 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
struct phy_device *phydev = phy_dat;
- if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev))
+ if (phydev->drv->did_interrupt && !phy_did_interrupt(phydev))
return IRQ_NONE;
if (phydev->drv->handle_interrupt) {
- if (phydev->drv->handle_interrupt(phydev))
+ if (phy_handle_interrupt(phydev))
goto phy_err;
} else {
/* reschedule state queue work to run as soon as possible */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index d941b8f4bad1..edc6bf40a0e4 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -230,7 +230,6 @@ extern struct phy_driver genphy_c45_driver;
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
-#ifdef CONFIG_PM
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{
struct device_driver *drv = phydev->mdio.dev.driver;
@@ -279,10 +278,13 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
return true;
}
-static int mdio_bus_phy_suspend(struct device *dev)
+static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
{
struct phy_device *phydev = to_phy_device(dev);
+ if (phydev->mac_managed_pm)
+ return 0;
+
/* We must stop the state machine manually, otherwise it stops out of
* control, possibly with the phydev->lock held. Upon resume, netdev
* may call phy routines that try to grab the same lock, and that may
@@ -299,61 +301,35 @@ static int mdio_bus_phy_suspend(struct device *dev)
return phy_suspend(phydev);
}
-static int mdio_bus_phy_resume(struct device *dev)
+static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
{
struct phy_device *phydev = to_phy_device(dev);
int ret;
+ if (phydev->mac_managed_pm)
+ return 0;
+
if (!phydev->suspended_by_mdio_bus)
goto no_resume;
phydev->suspended_by_mdio_bus = 0;
- ret = phy_resume(phydev);
+ ret = phy_init_hw(phydev);
if (ret < 0)
return ret;
-no_resume:
- if (phydev->attached_dev && phydev->adjust_link)
- phy_start_machine(phydev);
-
- return 0;
-}
-
-static int mdio_bus_phy_restore(struct device *dev)
-{
- struct phy_device *phydev = to_phy_device(dev);
- struct net_device *netdev = phydev->attached_dev;
- int ret;
-
- if (!netdev)
- return 0;
-
- ret = phy_init_hw(phydev);
+ ret = phy_resume(phydev);
if (ret < 0)
return ret;
-
+no_resume:
if (phydev->attached_dev && phydev->adjust_link)
phy_start_machine(phydev);
return 0;
}
-static const struct dev_pm_ops mdio_bus_phy_pm_ops = {
- .suspend = mdio_bus_phy_suspend,
- .resume = mdio_bus_phy_resume,
- .freeze = mdio_bus_phy_suspend,
- .thaw = mdio_bus_phy_resume,
- .restore = mdio_bus_phy_restore,
-};
-
-#define MDIO_BUS_PHY_PM_OPS (&mdio_bus_phy_pm_ops)
-
-#else
-
-#define MDIO_BUS_PHY_PM_OPS NULL
-
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend,
+ mdio_bus_phy_resume);
/**
* phy_register_fixup - creates a new phy_fixup and adds it to the list
@@ -551,10 +527,21 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_has_fixups);
+static ssize_t phy_dev_flags_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+
+ return sprintf(buf, "0x%08x\n", phydev->dev_flags);
+}
+static DEVICE_ATTR_RO(phy_dev_flags);
+
static struct attribute *phy_dev_attrs[] = {
&dev_attr_phy_id.attr,
&dev_attr_phy_interface.attr,
&dev_attr_phy_has_fixups.attr,
+ &dev_attr_phy_dev_flags.attr,
NULL,
};
ATTRIBUTE_GROUPS(phy_dev);
@@ -563,7 +550,7 @@ static const struct device_type mdio_bus_phy_type = {
.name = "PHY",
.groups = phy_dev_groups,
.release = phy_device_release,
- .pm = MDIO_BUS_PHY_PM_OPS,
+ .pm = pm_ptr(&mdio_bus_phy_pm_ops),
};
static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)
@@ -1103,10 +1090,19 @@ int phy_init_hw(struct phy_device *phydev)
if (ret < 0)
return ret;
- if (phydev->drv->config_init)
+ if (phydev->drv->config_init) {
ret = phydev->drv->config_init(phydev);
+ if (ret < 0)
+ return ret;
+ }
- return ret;
+ if (phydev->drv->config_intr) {
+ ret = phydev->drv->config_intr(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
}
EXPORT_SYMBOL(phy_init_hw);
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 1599ae74b066..809678750047 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2664,11 +2664,8 @@ mwifiex_cfg80211_sched_scan_start(struct wiphy *wiphy,
struct mwifiex_bg_scan_cfg *bgscan_cfg;
struct ieee_types_header *ie;
- if (!request || (!request->n_ssids && !request->n_match_sets)) {
- wiphy_err(wiphy, "%s : Invalid Sched_scan parameters",
- __func__);
+ if (!request || (!request->n_ssids && !request->n_match_sets))
return -EINVAL;
- }
wiphy_info(wiphy, "sched_scan start : n_ssids=%d n_match_sets=%d ",
request->n_ssids, request->n_match_sets);
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index a296eaf52a5b..6000ddf99fa3 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -440,6 +440,7 @@ int of_irq_count(struct device_node *dev)
return nr;
}
+EXPORT_SYMBOL_GPL(of_irq_count);
/**
* of_irq_to_resource_table - Fill in resource table with node's IRQ info
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 9ade93c3868b..b130a9282101 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -113,9 +113,10 @@ struct imx6_pcie_drvdata {
struct imx6_pcie {
struct dw_pcie *pci;
- int clkreq_gpio;
- int dis_gpio;
- int reset_gpio;
+ struct gpio_desc *clkreq_gpiod;
+ struct gpio_desc *dis_gpiod;
+ struct gpio_desc *power_on_gpiod;
+ struct gpio_desc *reset_gpiod;
bool gpio_active_high;
struct clk *pcie_bus;
struct clk *pcie_phy;
@@ -124,6 +125,7 @@ struct imx6_pcie {
struct clk *pciex2_per;
struct clk *pcie_inbound_axi;
struct clk *pcie;
+ struct clk *pcie_ext;
struct clk *pcie_aux;
struct clk *phy_per;
struct clk *misc_per;
@@ -854,7 +856,7 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
PHY_PLL_LOCK_WAIT_TIMEOUT))
dev_err(dev, "PCIe PLL lock timeout\n");
}
-static void imx8_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
+static int imx8_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
{
u32 val, retries = 0, tmp = 0, orig = 0;
struct dw_pcie *pci = imx6_pcie->pci;
@@ -926,10 +928,13 @@ static void imx8_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
break;
}
- if (retries >= PHY_PLL_LOCK_WAIT_MAX_RETRIES)
+ if (retries >= PHY_PLL_LOCK_WAIT_MAX_RETRIES) {
dev_err(dev, "PCIe PLL lock timeout\n");
- else
- dev_info(dev, "PCIe PLL locked after %d us.\n", retries * 10);
+ return -ENODEV;
+ }
+
+ dev_info(dev, "PCIe PLL locked after %d us.\n", retries * 10);
+ return 0;
}
static void imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
@@ -1133,6 +1138,9 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
+ if (imx6_pcie->dis_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->dis_gpiod, 1);
+
if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
int ret = regulator_disable(imx6_pcie->vpcie);
@@ -1140,6 +1148,12 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
dev_err(dev, "failed to disable vpcie regulator: %d\n",
ret);
}
+
+ /* Some boards don't have PCIe reset GPIO. */
+ if (imx6_pcie->reset_gpiod) {
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
+ !imx6_pcie->gpio_active_high);
+ }
}
static void imx6_pcie_set_l1_latency(struct imx6_pcie *imx6_pcie)
@@ -1169,7 +1183,7 @@ static void imx6_pcie_set_l1_latency(struct imx6_pcie *imx6_pcie)
}
}
-static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct dw_pcie *pci = imx6_pcie->pci;
struct device *dev = pci->dev;
@@ -1181,10 +1195,26 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
if (ret) {
dev_err(dev, "failed to enable vpcie regulator: %d\n",
ret);
- return;
+ return ret;
}
}
+ if (imx6_pcie->power_on_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->power_on_gpiod, 1);
+
+ if (imx6_pcie->clkreq_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->clkreq_gpiod, 1);
+
+ mdelay(2);
+ if (imx6_pcie->dis_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->dis_gpiod, 0);
+
+ ret = clk_prepare_enable(imx6_pcie->pcie_ext);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie_ext clock\n");
+ return ret;
+ }
+
switch (imx6_pcie->drvdata->variant) {
case IMX8QXP:
case IMX8QXP_EP:
@@ -1199,15 +1229,6 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
- /* Some boards don't have PCIe reset GPIO. */
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high);
- msleep(20);
- gpio_set_value_cansleep(imx6_pcie->reset_gpio,
- !imx6_pcie->gpio_active_high);
- }
-
switch (imx6_pcie->drvdata->variant) {
case IMX8QM:
case IMX8QM_EP:
@@ -1238,7 +1259,8 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
dev_err(dev, "ERROR PM_REQ_CORE_RST is still set.\n");
/* wait for phy pll lock firstly. */
- imx8_pcie_wait_for_phy_pll_lock(imx6_pcie);
+ if(imx8_pcie_wait_for_phy_pll_lock(imx6_pcie) != 0)
+ goto err_pll;
break;
case IMX8MQ:
case IMX8MM:
@@ -1246,7 +1268,19 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
case IMX8MM_EP:
reset_control_deassert(imx6_pcie->pciephy_reset);
- imx8_pcie_wait_for_phy_pll_lock(imx6_pcie);
+ if(imx8_pcie_wait_for_phy_pll_lock(imx6_pcie) != 0)
+ goto err_pll;
+ /*
+ * Set the over ride low and enabled
+ * make sure that REF_CLK is turned on.
+ */
+ val = imx6_pcie_grp_offset(imx6_pcie);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
+ 0);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, val,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
if (imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_L1SS)
/*
@@ -1312,7 +1346,8 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
IMX8MP_GPR_PCIE_CMN_RSTN,
IMX8MP_GPR_PCIE_CMN_RSTN);
- imx8_pcie_wait_for_phy_pll_lock(imx6_pcie);
+ if(imx8_pcie_wait_for_phy_pll_lock(imx6_pcie) != 0)
+ goto err_pll;
if (imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_L1SS)
/*
@@ -1364,7 +1399,38 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
- return;
+ /* Some boards don't have PCIe reset GPIO. */
+ if (imx6_pcie->reset_gpiod) {
+ msleep(100);
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
+ imx6_pcie->gpio_active_high);
+ /*
+ * PCI Express Base Specification:
+ * A delay of at least 100ms is required after PERST# is
+ * de-asserted before issuing any Configuration Requests
+ */
+ msleep(100);
+ }
+
+ return 0;
+
+err_pll:
+ if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie))
+ ret = regulator_disable(imx6_pcie->vpcie);
+
+ clk_disable_unprepare(imx6_pcie->pcie_ext);
+
+ switch (imx6_pcie->drvdata->variant) {
+ case IMX8QXP:
+ case IMX8QM:
+ case IMX8MP:
+ break;
+ default:
+ imx6_pcie_clk_disable(imx6_pcie);
+ break;
+ }
+
+ return -ENODEV;
}
static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
@@ -1900,10 +1966,8 @@ err_reset_phy:
imx6_pcie_clk_disable(imx6_pcie);
if (imx6_pcie->vpcie != NULL)
regulator_disable(imx6_pcie->vpcie);
- if (imx6_pcie->epdev_on != NULL)
- regulator_disable(imx6_pcie->epdev_on);
- if (gpio_is_valid(imx6_pcie->dis_gpio))
- gpio_set_value_cansleep(imx6_pcie->dis_gpio, 0);
+ if (imx6_pcie->dis_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->dis_gpiod, 0);
}
return ret;
@@ -1935,7 +1999,9 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
pci_imx_set_msi_en(pp);
if (imx6_pcie_establish_link(imx6_pcie))
return -ENODEV;
- dw_pcie_msi_init(pp);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ dw_pcie_msi_init(pp);
return 0;
}
@@ -2356,10 +2422,12 @@ static int imx6_pcie_resume_noirq(struct device *dev)
*/
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0);
+ msleep(10);
} else {
imx6_pcie_assert_core_reset(imx6_pcie);
imx6_pcie_init_phy(imx6_pcie);
- imx6_pcie_deassert_core_reset(imx6_pcie);
+ if(imx6_pcie_deassert_core_reset(imx6_pcie) == -ENODEV)
+ return -ENODEV;
dw_pcie_setup_rc(pp);
pci_imx_set_msi_en(pp);
@@ -2423,28 +2491,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
}
}
- imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
- if (IS_ERR(imx6_pcie->phy)) {
- if (PTR_ERR(imx6_pcie->phy) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- /* Set NULL if there is no pcie-phy */
- imx6_pcie->phy = NULL;
- }
+ /* pcie-phy uses in iMX8MP variant only */
+ if (imx6_pcie->drvdata->variant == IMX8MP) {
+ imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
+ if (IS_ERR(imx6_pcie->phy)) {
+ if (PTR_ERR(imx6_pcie->phy) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "couldn't get pcie-phy\n");
+ /* Set NULL if there is no pcie-phy */
+ imx6_pcie->phy = NULL;
+ }
- /* Find the HSIO MIX if one is defined, only imx8mp uses it */
- np = of_parse_phandle(node, "fsl,imx8mp-hsio-mix", 0);
- if (np) {
- struct resource res;
+ /* Find the HSIO MIX if one is defined, only imx8mp uses it */
+ np = of_parse_phandle(node, "fsl,imx8mp-hsio-mix", 0);
+ if (np) {
+ struct resource res;
- ret = of_address_to_resource(np, 0, &res);
- if (ret) {
- dev_err(dev, "Unable to find HSIO MIX res\n");
- return ret;
- }
- imx6_pcie->hsmix_base = devm_ioremap_resource(dev, &res);
- if (IS_ERR(imx6_pcie->hsmix_base)) {
- dev_err(dev, "Unable to map HSIO MIX res\n");
- return PTR_ERR(imx6_pcie->hsmix_base);
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret) {
+ dev_err(dev, "Unable to find HSIO MIX res\n");
+ return ret;
+ }
+ imx6_pcie->hsmix_base = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(imx6_pcie->hsmix_base)) {
+ dev_err(dev, "Unable to map HSIO MIX res\n");
+ return PTR_ERR(imx6_pcie->hsmix_base);
+ }
}
}
@@ -2465,43 +2537,48 @@ static int imx6_pcie_probe(struct platform_device *pdev)
imx6_pcie->l1ss_clkreq = 1;
/* Fetch GPIOs */
- imx6_pcie->clkreq_gpio = of_get_named_gpio(node, "clkreq-gpio", 0);
- if (gpio_is_valid(imx6_pcie->clkreq_gpio)) {
- devm_gpio_request_one(&pdev->dev, imx6_pcie->clkreq_gpio,
- GPIOF_OUT_INIT_LOW, "PCIe CLKREQ");
- } else if (imx6_pcie->clkreq_gpio == -EPROBE_DEFER) {
- return imx6_pcie->clkreq_gpio;
- }
-
- imx6_pcie->dis_gpio = of_get_named_gpio(node, "disable-gpio", 0);
- if (gpio_is_valid(imx6_pcie->dis_gpio)) {
- ret = devm_gpio_request_one(&pdev->dev, imx6_pcie->dis_gpio,
- GPIOF_OUT_INIT_LOW, "PCIe DIS");
- if (ret) {
+ imx6_pcie->clkreq_gpiod = devm_gpiod_get_optional(dev, "clkreq",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(imx6_pcie->clkreq_gpiod)) {
+ ret = PTR_ERR(imx6_pcie->clkreq_gpiod);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "unable to get clkreq gpio\n");
+ return ret;
+ }
+
+ imx6_pcie->dis_gpiod = devm_gpiod_get_optional(dev, "disable",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(imx6_pcie->dis_gpiod)) {
+ ret = PTR_ERR(imx6_pcie->dis_gpiod);
+ if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "unable to get disable gpio\n");
+ return ret;
+ }
+
+ imx6_pcie->power_on_gpiod = devm_gpiod_get_optional(dev, "power-on",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(imx6_pcie->power_on_gpiod)) {
+ ret = PTR_ERR(imx6_pcie->power_on_gpiod);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "unable to get power-on gpio\n");
return ret;
}
- } else if (imx6_pcie->dis_gpio == -EPROBE_DEFER) {
- return imx6_pcie->dis_gpio;
- }
+
imx6_pcie->epdev_on = devm_regulator_get(&pdev->dev, "epdev_on");
if (IS_ERR(imx6_pcie->epdev_on))
return -EPROBE_DEFER;
- imx6_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
+
imx6_pcie->gpio_active_high = of_property_read_bool(node,
"reset-gpio-active-high");
- if (gpio_is_valid(imx6_pcie->reset_gpio)) {
- ret = devm_gpio_request_one(dev, imx6_pcie->reset_gpio,
- imx6_pcie->gpio_active_high ?
- GPIOF_OUT_INIT_HIGH :
- GPIOF_OUT_INIT_LOW,
- "PCIe reset");
- if (ret) {
+ imx6_pcie->reset_gpiod = devm_gpiod_get_optional(dev, "reset",
+ imx6_pcie->gpio_active_high ?
+ GPIOD_OUT_LOW :
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(imx6_pcie->reset_gpiod)) {
+ ret = PTR_ERR(imx6_pcie->reset_gpiod);
+ if (ret != -EPROBE_DEFER)
dev_err(dev, "unable to get reset gpio\n");
- return ret;
- }
- } else if (imx6_pcie->reset_gpio == -EPROBE_DEFER) {
- return imx6_pcie->reset_gpio;
+ return ret;
}
/* Fetch clocks */
@@ -2523,6 +2600,13 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie);
}
+ imx6_pcie->pcie_ext = devm_clk_get_optional(&pdev->dev, "pcie_ext");
+ if (IS_ERR(imx6_pcie->pcie_ext)) {
+ dev_err(&pdev->dev,
+ "pcie_ext clock source missing or invalid\n");
+ return PTR_ERR(imx6_pcie->pcie_ext);
+ }
+
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
case IMX6SX_EP:
@@ -2716,12 +2800,17 @@ static int imx6_pcie_probe(struct platform_device *pdev)
dev_err(dev, "failed to enable the epdev_on regulator\n");
goto err_ret;
}
- if (gpio_is_valid(imx6_pcie->dis_gpio))
- gpio_set_value_cansleep(imx6_pcie->dis_gpio, 1);
+ if (imx6_pcie->dis_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->dis_gpiod, 1);
imx6_pcie_assert_core_reset(imx6_pcie);
imx6_pcie_init_phy(imx6_pcie);
- imx6_pcie_deassert_core_reset(imx6_pcie);
+ ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+ if (ret == -ENODEV) {
+ if (imx6_pcie->power_on_gpiod)
+ gpiod_set_value_cansleep(imx6_pcie->power_on_gpiod, 0);
+ goto err_reg;
+ }
imx6_setup_phy_mpll(imx6_pcie);
val = dw_pcie_readl_dbi(pci, PCIE_AMBA_ORDERING_CTRL_OFF);
@@ -2744,7 +2833,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
} else {
dev_err(dev, "unable to add pcie port.\n");
}
- goto err_ret;
+ goto err_reg;
}
pci_imx_set_msi_en(&imx6_pcie->pci->pp);
@@ -2763,6 +2852,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return 0;
+err_reg:
+ regulator_disable(imx6_pcie->epdev_on);
err_ret:
imx6_pcie_detach_pd(dev);
return ret;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index b7ad4fef544b..a8676d7b1977 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2507,6 +2507,21 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
quirk_unhide_mch_dev6);
+#ifdef CONFIG_PCI_FORCE_GEN1
+/*
+ * The Apalis evaluation board needs to set the link speed to 2.5 GT/s (GEN1).
+ * The default link speed setting is 5 GT/s (GEN2). 0x98 is the Link Control 2
+ * PCIe Capability Register of the PEX8605 PCIe switch. The switch supports
+ * link speed auto negotiation, but falsely sets the link speed to 5 GT/s.
+ */
+static void quirk_apalis_plx_gen1(struct pci_dev *dev)
+{
+ pci_write_config_dword(dev, 0x98, 0x1);
+ mdelay(50);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8605, quirk_apalis_plx_gen1);
+#endif /* CONFIG_PCI_FORCE_GEN1 */
+
#ifdef CONFIG_PCI_MSI
/*
* Some chipsets do not support MSI. We cannot easily rely on setting
@@ -3274,6 +3289,15 @@ static void fixup_ti816x_class(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800,
PCI_CLASS_NOT_DEFINED, 8, fixup_ti816x_class);
+/* TW6869 Frame grabber has same problem as ti816x */
+static void fixup_tw6869_class(struct pci_dev* dev)
+{
+ dev_info(&dev->dev, "Setting PCI class for tw6869 PCIe device\n");
+ dev->class = PCI_CLASS_MULTIMEDIA_VIDEO;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869,
+ PCI_CLASS_NOT_DEFINED, 0, fixup_tw6869_class);
+
/*
* Some PCIe devices do not work reliably with the claimed maximum
* payload size supported.
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 5947cba737f8..1ebc661d0654 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -917,8 +917,22 @@ static long samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
if (phy_cfg->clk_rate == rate)
break;
- if (phy_cfg->clk_rate == 0)
- return -EINVAL;
+ if (phy_cfg->clk_rate == 0) {
+ /* If no exact setting found, try to find a close one */
+ phy_cfg = samsung_phy_pll_cfg;
+ phy_cfg++;
+ for (; phy_cfg->clk_rate != 0; phy_cfg++)
+ if (phy_cfg->clk_rate > rate)
+ break;
+
+ /* Bail out, no suitable setting found */
+ if (phy_cfg->clk_rate == 0)
+ return -EINVAL;
+
+ /* Use the next lower rate if that is closer to the wanted one */
+ if ((phy_cfg->clk_rate - rate) > (rate - (phy_cfg-1)->clk_rate))
+ phy_cfg--;
+ }
return phy_cfg->clk_rate;
}
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
index 97d1f58efef4..0ca8e871779f 100644
--- a/drivers/power/reset/gpio-poweroff.c
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -24,6 +24,7 @@ static struct gpio_desc *reset_gpio;
static u32 timeout = DEFAULT_TIMEOUT_MS;
static u32 active_delay = 100;
static u32 inactive_delay = 100;
+static void *prev_pm_power_off = NULL;
static void gpio_poweroff_do_poweroff(void)
{
@@ -49,14 +50,28 @@ static void gpio_poweroff_do_poweroff(void)
static int gpio_poweroff_probe(struct platform_device *pdev)
{
bool input = false;
+ bool force = false;
enum gpiod_flags flags;
- /* If a pm_power_off function has already been added, leave it alone */
+
+ force = of_property_read_bool(pdev->dev.of_node, "force-mode");
+
+ /*
+ * If a pm_power_off function has already been added, leave it alone,
+ * if force-mode is not enabled.
+ */
if (pm_power_off != NULL) {
- dev_err(&pdev->dev,
- "%s: pm_power_off function already registered",
- __func__);
- return -EBUSY;
+ if (force) {
+ dev_warn(&pdev->dev,
+ "%s: pm_power_off function replaced",
+ __func__);
+ prev_pm_power_off = pm_power_off;
+ } else {
+ dev_err(&pdev->dev,
+ "%s: pm_power_off function already registered",
+ __func__);
+ return -EBUSY;
+ }
}
input = device_property_read_bool(&pdev->dev, "input");
@@ -81,7 +96,7 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
static int gpio_poweroff_remove(struct platform_device *pdev)
{
if (pm_power_off == &gpio_poweroff_do_poweroff)
- pm_power_off = NULL;
+ pm_power_off = prev_pm_power_off;
return 0;
}
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 6b9ce8f34e0e..442faa078e3a 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -594,6 +594,12 @@ static int pca9450_buck123_dvs_init(struct pca9450_pmic *pmic)
}
}
}
+ /* clear the preset enable bit as we use PCA9450_BUCKxOUT_DVSy regs */
+ ret = pca9450_clear_bits(pca9450, PCA9450_BUCK123_DVS, \
+ BUCK123_PRESET_EN);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 5cd69052e79e..451a7e82f916 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -55,6 +55,14 @@ config RPMSG_VIRTIO
select RPMSG
select VIRTIO
+config RPMSG_VIRTIO_CHAR
+ bool "Enable Virtio RPMSG char device driver support"
+ default y
+ depends on RPMSG_VIRTIO
+ depends on RPMSG_CHAR
+ help
+ Say y here to enable to use RPMSG char device interface.
+
config HAVE_IMX_RPMSG
bool "IMX RPMSG driver on the AMP SOCs"
default y
diff --git a/drivers/rpmsg/imx_rpmsg.c b/drivers/rpmsg/imx_rpmsg.c
index b93df26bd21b..ce20150e7102 100644
--- a/drivers/rpmsg/imx_rpmsg.c
+++ b/drivers/rpmsg/imx_rpmsg.c
@@ -531,6 +531,7 @@ err_out:
static int imx_rpmsg_probe(struct platform_device *pdev)
{
int j, ret = 0;
+ unsigned long variant;
char *buf;
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
@@ -548,7 +549,8 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
#ifdef CONFIG_IMX_SCU
rpdev->proc_nb.notifier_call = imx_rpmsg_partition_notify;
#endif
- rpdev->variant = (enum imx_rpmsg_variants)of_device_get_match_data(dev);
+ variant = (uintptr_t)of_device_get_match_data(dev);
+ rpdev->variant = (enum imx_rpmsg_variants)variant;
rpdev->rx_buffer.buf = buf;
rpdev->rx_buffer.head = 0;
rpdev->rx_buffer.tail = 0;
diff --git a/drivers/rpmsg/imx_rpmsg_tty.c b/drivers/rpmsg/imx_rpmsg_tty.c
index 008c998b610e..96d39616f34f 100644
--- a/drivers/rpmsg/imx_rpmsg_tty.c
+++ b/drivers/rpmsg/imx_rpmsg_tty.c
@@ -30,9 +30,16 @@ struct rpmsgtty_port {
static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len,
void *priv, u32 src)
{
- int space;
- unsigned char *cbuf;
+ int copied;
struct rpmsgtty_port *cport = dev_get_drvdata(&rpdev->dev);
+ struct tty_struct *tty = dev_get_drvdata(&rpdev->dev);
+
+ /* no one left to give data to, so sleep */
+ if (tty == NULL) {
+ dev_dbg(&rpdev->dev, "waiting for readers, discard len %d\n",
+ len);
+ return -ENOTTY;
+ }
/* flush the recv-ed none-zero data to tty node */
if (len == 0)
@@ -40,18 +47,14 @@ static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len,
dev_dbg(&rpdev->dev, "msg(<- src 0x%x) len %d\n", src, len);
- print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
- data, len, true);
+ print_hex_dump_debug(__func__, DUMP_PREFIX_NONE, 16, 1,
+ data, len, true);
spin_lock_bh(&cport->rx_lock);
- space = tty_prepare_flip_string(&cport->port, &cbuf, len);
- if (space <= 0) {
- dev_err(&rpdev->dev, "No memory for tty_prepare_flip_string\n");
- spin_unlock_bh(&cport->rx_lock);
- return -ENOMEM;
- }
+ copied = tty_insert_flip_string(&cport->port, data, len);
+ if (copied != len)
+ dev_err_ratelimited(&rpdev->dev, "RX copy to tty layer failed\n");
- memcpy(cbuf, data, len);
tty_flip_buffer_push(&cport->port);
spin_unlock_bh(&cport->rx_lock);
@@ -153,6 +156,9 @@ static int rpmsg_tty_probe(struct rpmsg_device *rpdev)
rpmsgtty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
rpmsgtty_driver->init_termios = tty_std_termios;
+ /* set default to no chracter echoing of the tty driver */
+ rpmsgtty_driver->init_termios.c_lflag = rpmsgtty_driver->init_termios.c_lflag & ~ECHO;
+
tty_set_operations(rpmsgtty_driver, &imxrpmsgtty_ops);
tty_port_init(&cport->port);
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 376ebbf880d6..2c4c51ec04fe 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -67,6 +67,9 @@ struct virtproc_info {
wait_queue_head_t sendq;
atomic_t sleepers;
struct rpmsg_endpoint *ns_ept;
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct list_head rsvcs;
+#endif
};
/* The feature bitmap for virtio rpmsg */
@@ -133,6 +136,35 @@ struct virtio_rpmsg_channel {
#define to_virtio_rpmsg_channel(_rpdev) \
container_of(_rpdev, struct virtio_rpmsg_channel, rpdev)
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+/**
+ * struct virtio_rpmsg_rsvc - virtio RPMsg remote service
+ * @name: name of the RPMsg remote service
+ * @addr: RPMsg address of the remote service
+ * @ept: local endpoint bound to the remote service
+ * @node: list node
+ */
+struct virtio_rpmsg_rsvc {
+ char name[RPMSG_NAME_SIZE];
+ u32 addr;
+ struct rpmsg_endpoint *ept;
+ struct list_head node;
+};
+
+/**
+ * struct virtio_rpmsg_ept - virtio RPMsg endpoint
+ * @rsvc: RPMsg service
+ * @ept: RPMsg endpoint
+ *
+ */
+struct virtio_rpmsg_ept {
+ struct virtio_rpmsg_rsvc *rsvc;
+ struct rpmsg_endpoint ept;
+};
+
+#define to_virtio_rpmsg_ept(_ept) \
+ container_of(_ept, struct virtio_rpmsg_ept, ept)
+#endif
/*
* We're allocating buffers of 512 bytes each for communications. The
* number of buffers will be computed from the number of buffers supported
@@ -208,6 +240,199 @@ rpmsg_sg_init(struct scatterlist *sg, void *cpu_addr, unsigned int len)
}
}
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+/**
+ * virtio_rpmsg_find_rsvc_by_name - find the announced remote service
+ * @vrp: virtio remote proc information
+ * @name: remote service name
+ *
+ * The caller is supposed to have mutex lock before calling this function
+ *
+ * return NULL if no remote service has been found, otherwise, return
+ * the remote service pointer.
+ */
+static struct virtio_rpmsg_rsvc *
+virtio_rpmsg_find_rsvc_by_name(struct virtproc_info *vrp, char *name)
+{
+ struct virtio_rpmsg_rsvc *rsvc;
+
+ list_for_each_entry(rsvc, &vrp->rsvcs, node) {
+ if (!strncmp(rsvc->name, name, RPMSG_NAME_SIZE))
+ /* remote service has found */
+ return rsvc;
+ }
+
+ return NULL;
+}
+
+/**
+ * virtio_rpmsg_create_rsvc_by_name - create remote service
+ * @vrp: virtio remote proc information
+ * @name: remote service name
+ *
+ * The caller is supposed to have mutex lock before calling this function
+ *
+ * return NULL if remote service creation failed. otherwise, return
+ * the remote service pointer.
+ */
+static struct virtio_rpmsg_rsvc *
+virtio_rpmsg_create_rsvc_by_name(struct virtproc_info *vrp, char *name)
+{
+ struct virtio_rpmsg_rsvc *rsvc;
+
+ rsvc = virtio_rpmsg_find_rsvc_by_name(vrp, name);
+ if (rsvc)
+ return rsvc;
+ rsvc = kzalloc(sizeof(*rsvc), GFP_KERNEL);
+ if (!rsvc)
+ return NULL;
+ strncpy(rsvc->name, name, RPMSG_NAME_SIZE);
+ list_add_tail(&rsvc->node, &vrp->rsvcs);
+ return rsvc;
+}
+
+/**
+ * virtio_rpmsg_remove_rsvc_by_name - remove remote service
+ * @vrp: virtio remote proc information
+ * @name: remote service name
+ *
+ */
+static void
+virtio_rpmsg_remove_rsvc_by_name(struct virtproc_info *vrp, char *name)
+{
+ struct virtio_rpmsg_rsvc *rsvc;
+ struct rpmsg_endpoint *ept;
+ struct virtio_rpmsg_ept *vept;
+
+ mutex_lock(&vrp->endpoints_lock);
+ list_for_each_entry(rsvc, &vrp->rsvcs, node) {
+ if (!strncmp(rsvc->name, name, RPMSG_NAME_SIZE)) {
+ /* remote service has found, no need to
+ * create
+ */
+ ept = rsvc->ept;
+ if (ept) {
+ vept = to_virtio_rpmsg_ept(ept);
+ vept->rsvc = NULL;
+ }
+ list_del(&rsvc->node);
+ kfree(rsvc);
+ break;
+ }
+ }
+ mutex_unlock(&vrp->endpoints_lock);
+}
+
+/**
+ * virtio_rpmsg_create_rsvc - create remote service with channel information
+ * @vrp: virtio remote proc information
+ * @chinfo: channel information
+ *
+ * return remote service pointer if it is successfully created; otherwise,
+ * return NULL.
+ */
+static struct virtio_rpmsg_rsvc *
+virtio_rpmsg_create_rsvc(struct virtproc_info *vrp,
+ struct rpmsg_channel_info *chinfo)
+{
+ struct virtio_rpmsg_rsvc *rsvc;
+
+ mutex_lock(&vrp->endpoints_lock);
+ rsvc = virtio_rpmsg_create_rsvc_by_name(vrp, chinfo->name);
+ if (rsvc) {
+ struct virtio_device *vdev = vrp->vdev;
+
+ rsvc->addr = chinfo->dst;
+ dev_info(&vdev->dev, "Remote has announced service %s, %d.\n",
+ chinfo->name, rsvc->addr);
+ }
+ mutex_unlock(&vrp->endpoints_lock);
+ return rsvc;
+}
+
+/**
+ * virtio_rpmsg_announce_ept_create - announce endpoint has been created
+ * @ept: RPMsg endpoint
+ *
+ * return 0 if succeeded, otherwise, return error code.
+ */
+static int virtio_rpmsg_announce_ept_create(struct rpmsg_endpoint *ept)
+{
+ struct virtio_rpmsg_ept *vept = to_virtio_rpmsg_ept(ept);
+ struct virtio_rpmsg_rsvc *rsvc = vept->rsvc;
+ struct rpmsg_device *rpdev = ept->rpdev;
+ struct virtio_rpmsg_channel *vch;
+ struct virtproc_info *vrp;
+ struct device *dev;
+ int err = 0;
+
+ if (!rpdev)
+ /* If the endpoint is not connected to a RPMsg device,
+ * no need to send the announcement.
+ */
+ return 0;
+ vch = to_virtio_rpmsg_channel(rpdev);
+ vrp = vch->vrp;
+ dev = &ept->rpdev->dev;
+ /* need to tell remote processor's name service about this channel ? */
+ if (virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+ struct rpmsg_ns_msg nsm;
+
+ strncpy(nsm.name, rsvc->name, RPMSG_NAME_SIZE);
+ nsm.addr = ept->addr;
+ nsm.flags = RPMSG_NS_CREATE;
+
+ err = rpmsg_sendto(ept, &nsm, sizeof(nsm),
+ RPMSG_NS_ADDR);
+ if (err)
+ dev_err(dev, "failed to announce service %d\n", err);
+ }
+
+ return err;
+}
+
+/**
+ * virtio_rpmsg_announce_ept_destroy - announce endpoint has been destroyed
+ * @ept: RPMsg endpoint
+ *
+ * return 0 if succeeded, otherwise, return error code.
+ */
+static int virtio_rpmsg_announce_ept_destroy(struct rpmsg_endpoint *ept)
+{
+ struct virtio_rpmsg_ept *vept = to_virtio_rpmsg_ept(ept);
+ struct virtio_rpmsg_rsvc *rsvc = vept->rsvc;
+ struct rpmsg_device *rpdev = ept->rpdev;
+ struct virtio_rpmsg_channel *vch;
+ struct virtproc_info *vrp;
+ struct device *dev;
+ int err = 0;
+
+ if (!rpdev)
+ /* If the endpoint is not connected to a RPMsg device,
+ * no need to send the announcement.
+ */
+ return 0;
+ vch = to_virtio_rpmsg_channel(rpdev);
+ vrp = vch->vrp;
+ dev = &ept->rpdev->dev;
+ /* tell remote processor's name service we're removing this channel */
+ if (virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+ struct rpmsg_ns_msg nsm;
+
+ strncpy(nsm.name, rsvc->name, RPMSG_NAME_SIZE);
+ nsm.addr = ept->addr;
+ nsm.flags = RPMSG_NS_DESTROY;
+
+ err = rpmsg_sendto(ept, &nsm, sizeof(nsm),
+ RPMSG_NS_ADDR);
+ if (err)
+ dev_err(dev, "failed to announce service %d\n", err);
+ }
+
+ return err;
+}
+#endif
+
/**
* __ept_release() - deallocate an rpmsg endpoint
* @kref: the ept's reference count
@@ -221,27 +446,53 @@ static void __ept_release(struct kref *kref)
{
struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint,
refcount);
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_ept *vept = to_virtio_rpmsg_ept(ept);
+ struct virtio_rpmsg_channel *vch;
+ struct virtproc_info *vrp;
+
+ if (ept->rpdev) {
+ vch = to_virtio_rpmsg_channel(ept->rpdev);
+ vrp = vch->vrp;
+ (void)virtio_rpmsg_announce_ept_destroy(ept);
+ mutex_lock(&vrp->endpoints_lock);
+ vept->rsvc->ept = NULL;
+ mutex_unlock(&vrp->endpoints_lock);
+ }
+ kfree(vept);
+#else
/*
* At this point no one holds a reference to ept anymore,
* so we can directly free it
*/
kfree(ept);
+#endif
}
/* for more info, see below documentation of rpmsg_create_ept() */
static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
struct rpmsg_device *rpdev,
rpmsg_rx_cb_t cb,
- void *priv, u32 addr)
+ void *priv,
+ struct rpmsg_channel_info *ch)
{
int id_min, id_max, id;
struct rpmsg_endpoint *ept;
+ u32 addr = ch->src;
struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev;
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_ept *vept;
+ struct virtio_rpmsg_rsvc *rsvc;
+ vept = kzalloc(sizeof(*vept), GFP_KERNEL);
+ if (!vept)
+ return NULL;
+ ept = &vept->ept;
+#else
ept = kzalloc(sizeof(*ept), GFP_KERNEL);
if (!ept)
return NULL;
-
+#endif
kref_init(&ept->refcount);
mutex_init(&ept->cb_lock);
@@ -251,7 +502,7 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
ept->ops = &virtio_endpoint_ops;
/* do we need to allocate a local address ? */
- if (addr == RPMSG_ADDR_ANY) {
+ if (ch->src == RPMSG_ADDR_ANY) {
id_min = RPMSG_RESERVED_ADDRESSES;
id_max = 0;
} else {
@@ -268,7 +519,18 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
goto free_ept;
}
ept->addr = id;
-
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ if (ept->addr != RPMSG_NS_ADDR) {
+ rsvc = virtio_rpmsg_create_rsvc_by_name(vrp, ch->name);
+ if (!rsvc)
+ goto free_ept;
+ vept->rsvc = rsvc;
+ rsvc->ept = ept;
+ dev_info(&vrp->vdev->dev, "RPMsg ept created, %s:%d,%d.\n",
+ ch->name, ept->addr, rsvc->addr);
+ (void)virtio_rpmsg_announce_ept_create(ept);
+ }
+#endif
mutex_unlock(&vrp->endpoints_lock);
return ept;
@@ -285,8 +547,7 @@ static struct rpmsg_endpoint *virtio_rpmsg_create_ept(struct rpmsg_device *rpdev
struct rpmsg_channel_info chinfo)
{
struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
-
- return __rpmsg_create_ept(vch->vrp, rpdev, cb, priv, chinfo.src);
+ return __rpmsg_create_ept(vch->vrp, rpdev, cb, priv, &chinfo);
}
/**
@@ -384,6 +645,7 @@ static void virtio_rpmsg_release_device(struct device *dev)
kfree(vch);
}
+#ifndef CONFIG_RPMSG_VIRTIO_CHAR
/*
* create an rpmsg channel using its name and address info.
* this function will be used to create both static and dynamic
@@ -436,6 +698,7 @@ static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp,
return rpdev;
}
+#endif
/* super simple buffer "allocator" that is just enough for now */
static void *get_a_tx_buf(struct virtproc_info *vrp)
@@ -677,7 +940,16 @@ static int virtio_rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src,
static int virtio_rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len)
{
struct rpmsg_device *rpdev = ept->rpdev;
- u32 src = ept->addr, dst = rpdev->dst;
+ u32 src = ept->addr;
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_ept *vept = to_virtio_rpmsg_ept(ept);
+ u32 dst = vept->rsvc->addr;
+
+ if (dst == RPMSG_ADDR_ANY)
+ return -EPIPE;
+#else
+ u32 dst = rpdev->dst;
+#endif
return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
}
@@ -816,12 +1088,13 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
void *priv, u32 src)
{
struct rpmsg_ns_msg *msg = data;
- struct rpmsg_device *newch;
struct rpmsg_channel_info chinfo;
struct virtproc_info *vrp = priv;
struct device *dev = &vrp->vdev->dev;
+#ifndef CONFIG_RPMSG_VIRTIO_CHAR
+ struct rpmsg_device *newch;
int ret;
-
+#endif
#if defined(CONFIG_DYNAMIC_DEBUG)
dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1,
data, len, true);
@@ -855,13 +1128,25 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
chinfo.dst = msg->addr;
if (msg->flags & RPMSG_NS_DESTROY) {
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ virtio_rpmsg_remove_rsvc_by_name(vrp, chinfo.name);
+#else
ret = rpmsg_unregister_device(&vrp->vdev->dev, &chinfo);
if (ret)
dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
+#endif
} else {
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_rsvc *rsvc;
+
+ rsvc = virtio_rpmsg_create_rsvc(vrp, &chinfo);
+ if (!rsvc)
+ dev_err(dev, "virtio_rpmsg_create_rsvc failed\n");
+#else
newch = rpmsg_create_channel(vrp, &chinfo);
if (!newch)
dev_err(dev, "rpmsg_create_channel failed\n");
+#endif
}
return 0;
@@ -877,6 +1162,10 @@ static int rpmsg_probe(struct virtio_device *vdev)
int err = 0, i;
size_t total_buf_space;
bool notify;
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_channel *vch;
+ struct rpmsg_device *rp_char_dev;
+#endif
vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
if (!vrp)
@@ -948,16 +1237,45 @@ static int rpmsg_probe(struct virtio_device *vdev)
/* if supported by the remote processor, enable the name service */
if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) {
+ struct rpmsg_channel_info ns_chinfo;
+
+ ns_chinfo.src = RPMSG_NS_ADDR;
+ ns_chinfo.dst = RPMSG_NS_ADDR;
+ strcpy(ns_chinfo.name, "name_service");
/* a dedicated endpoint handles the name service msgs */
vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb,
- vrp, RPMSG_NS_ADDR);
+ vrp, &ns_chinfo);
if (!vrp->ns_ept) {
dev_err(&vdev->dev, "failed to create the ns ept\n");
err = -ENOMEM;
goto free_coherent;
}
}
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ vch = kzalloc(sizeof(*vch), GFP_KERNEL);
+ if (!vch) {
+ err = -ENOMEM;
+ goto free_coherent;
+ }
+
+ /* Link the channel to our vrp */
+ vch->vrp = vrp;
+ /* Initialize remote services list */
+ INIT_LIST_HEAD(&vrp->rsvcs);
+
+ /* Assign public information to the rpmsg_device */
+ rp_char_dev = &vch->rpdev;
+ rp_char_dev->ops = &virtio_rpmsg_ops;
+ rp_char_dev->dev.parent = &vrp->vdev->dev;
+ rp_char_dev->dev.release = virtio_rpmsg_release_device;
+ err = rpmsg_chrdev_register_device(rp_char_dev);
+ if (err) {
+ kfree(vch);
+ goto free_coherent;
+ }
+ dev_info(&vdev->dev, "Registered as RPMsg char device.\n");
+#endif
/*
* Prepare to kick but don't notify yet - we can't do this before
* device is ready.
@@ -1001,6 +1319,9 @@ static void rpmsg_remove(struct virtio_device *vdev)
struct virtproc_info *vrp = vdev->priv;
size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
int ret;
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ struct virtio_rpmsg_rsvc *rsvc, *tmp;
+#endif
vdev->config->reset(vdev);
@@ -1013,6 +1334,12 @@ static void rpmsg_remove(struct virtio_device *vdev)
idr_destroy(&vrp->endpoints);
+#ifdef CONFIG_RPMSG_VIRTIO_CHAR
+ list_for_each_entry_safe(rsvc, tmp, &vrp->rsvcs, node) {
+ list_del(&rsvc->node);
+ kfree(rsvc);
+ }
+#endif
vdev->config->del_vqs(vrp->vdev);
dma_free_coherent(vdev->dev.parent, total_buf_space,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 99b93f56a2d5..a179b92aaf69 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -121,6 +121,9 @@ enum ds_type {
#define RX8130_REG_FLAG_AF BIT(3)
#define RX8130_REG_CONTROL0 0x1e
#define RX8130_REG_CONTROL0_AIE BIT(3)
+#define RX8130_REG_CONTROL1 0x1f
+#define RX8130_REG_CONTROL1_INIEN BIT(4)
+#define RX8130_REG_CONTROL1_CHGEN BIT(5)
#define MCP794XX_REG_CONTROL 0x07
# define MCP794XX_BIT_ALM0_EN 0x10
@@ -180,6 +183,15 @@ struct chip_desc {
u16 trickle_charger_reg;
u8 (*do_trickle_setup)(struct ds1307 *, u32,
bool);
+ /* Does the RTC require trickle-resistor-ohms to select the value of
+ * the resistor between Vcc and Vbackup?
+ */
+ bool requires_trickle_resistor;
+ /* Some RTC's batteries and supercaps were charged by default, others
+ * allow charging but were not configured previously to do so.
+ * Remember this behavior to stay backwards compatible.
+ */
+ bool charge_default;
};
static const struct chip_desc chips[last_ds_type];
@@ -498,6 +510,8 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
DS1307_TRICKLE_CHARGER_NO_DIODE;
+ setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
+
switch (ohms) {
case 250:
setup |= DS1307_TRICKLE_CHARGER_250_OHM;
@@ -516,6 +530,16 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
return setup;
}
+static u8 do_trickle_setup_rx8130(struct ds1307 *ds1307, u32 ohms, bool diode)
+{
+ /* make sure that the backup battery is enabled */
+ u8 setup = RX8130_REG_CONTROL1_INIEN;
+ if (diode)
+ setup |= RX8130_REG_CONTROL1_CHGEN;
+
+ return setup;
+}
+
static irqreturn_t rx8130_irq(int irq, void *dev_id)
{
struct ds1307 *ds1307 = dev_id;
@@ -904,6 +928,8 @@ static const struct chip_desc chips[last_ds_type] = {
.bbsqi_bit = DS1339_BIT_BBSQI,
.trickle_charger_reg = 0x10,
.do_trickle_setup = &do_trickle_setup_ds1339,
+ .requires_trickle_resistor = true,
+ .charge_default = true,
},
[ds_1340] = {
.century_reg = DS1307_REG_HOUR,
@@ -911,6 +937,8 @@ static const struct chip_desc chips[last_ds_type] = {
.century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08,
+ .requires_trickle_resistor = true,
+ .charge_default = true,
},
[ds_1341] = {
.century_reg = DS1307_REG_MONTH,
@@ -934,6 +962,8 @@ static const struct chip_desc chips[last_ds_type] = {
.offset = 0x10,
.irq_handler = rx8130_irq,
.rtc_ops = &rx8130_rtc_ops,
+ .trickle_charger_reg = RX8130_REG_CONTROL1,
+ .do_trickle_setup = &do_trickle_setup_rx8130,
},
[m41t0] = {
.rtc_ops = &m41txx_rtc_ops,
@@ -1218,18 +1248,37 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
static u8 ds1307_trickle_init(struct ds1307 *ds1307,
const struct chip_desc *chip)
{
- u32 ohms;
- bool diode = true;
+ u32 ohms, chargeable;
+ bool diode = chip->charge_default;
if (!chip->do_trickle_setup)
return 0;
if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms",
- &ohms))
+ &ohms) && chip->requires_trickle_resistor)
return 0;
- if (device_property_read_bool(ds1307->dev, "trickle-diode-disable"))
+ /* aux-voltage-chargeable takes precedence over the deprecated
+ * trickle-diode-disable
+ */
+ if (!device_property_read_u32(ds1307->dev, "aux-voltage-chargeable",
+ &chargeable)) {
+ switch (chargeable) {
+ case 0:
+ diode = false;
+ break;
+ case 1:
+ diode = true;
+ break;
+ default:
+ dev_warn(ds1307->dev,
+ "unsupported aux-voltage-chargeable value\n");
+ break;
+ }
+ } else if (device_property_read_bool(ds1307->dev,
+ "trickle-diode-disable")) {
diode = false;
+ }
return chip->do_trickle_setup(ds1307, ohms, diode);
}
@@ -1635,7 +1684,6 @@ static int ds1307_probe(struct i2c_client *client,
trickle_charger_setup = pdata->trickle_charger_setup;
if (trickle_charger_setup && chip->trickle_charger_reg) {
- trickle_charger_setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
dev_dbg(ds1307->dev,
"writing trickle charger info 0x%x to 0x%x\n",
trickle_charger_setup, chip->trickle_charger_reg);
diff --git a/drivers/soc/imx/soc-imx-scu.c b/drivers/soc/imx/soc-imx-scu.c
index a34bd2b469ea..720b15972c21 100644
--- a/drivers/soc/imx/soc-imx-scu.c
+++ b/drivers/soc/imx/soc-imx-scu.c
@@ -35,26 +35,31 @@ struct imx_sc_msg_misc_get_soc_uid {
u32 uid_high;
} __packed;
-static int imx_scu_soc_uid(u64 *soc_uid)
+static ssize_t soc_uid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct imx_sc_msg_misc_get_soc_uid msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
- int ret;
+ u64 soc_uid;
+
+ memset(&msg, 0, sizeof(msg));
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_MISC;
hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID;
hdr->size = 1;
- ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true);
+ imx_scu_call_rpc(soc_ipc_handle, &msg, true);
- *soc_uid = msg.uid_high;
- *soc_uid <<= 32;
- *soc_uid |= msg.uid_low;
+ soc_uid = msg.uid_high;
+ soc_uid <<= 32;
+ soc_uid |= msg.uid_low;
- return ret;
+ return sprintf(buf, "%016llX\n", soc_uid);
}
+static DEVICE_ATTR_RO(soc_uid);
+
static int imx_scu_soc_id(void)
{
struct imx_sc_msg_misc_get_soc_id msg;
@@ -83,7 +88,6 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
struct soc_device_attribute *soc_dev_attr;
struct soc_device *soc_dev;
int id, ret;
- u64 uid = 0;
u32 val;
ret = imx_scu_get_handle(&soc_ipc_handle);
@@ -107,10 +111,6 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
if (id < 0)
return -EINVAL;
- ret = imx_scu_soc_uid(&uid);
- if (ret < 0)
- return -EINVAL;
-
/* format soc_id value passed from SCU firmware */
val = id & 0x1f;
if (of_machine_is_compatible("fsl,imx8qm")) {
@@ -133,22 +133,19 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
goto free_soc_id;
}
- soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", uid);
- if (!soc_dev_attr->serial_number) {
- ret = -ENOMEM;
- goto free_revision;
- }
-
soc_dev = soc_device_register(soc_dev_attr);
if (IS_ERR(soc_dev)) {
ret = PTR_ERR(soc_dev);
- goto free_serial_number;
+ goto free_revision;
}
+ ret = device_create_file(soc_device_to_device(soc_dev),
+ &dev_attr_soc_uid);
+ if (ret)
+ goto free_revision;
+
return 0;
-free_serial_number:
- kfree(soc_dev_attr->serial_number);
free_revision:
kfree(soc_dev_attr->revision);
free_soc_id:
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index bdaeca3b47ea..aaae4e33bbc6 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -900,6 +900,11 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
goto out_controller_put;
}
+ if (cs_gpio == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out_controller_put;
+ }
+
if (!gpio_is_valid(cs_gpio) && lpspi_platform_info)
cs_gpio = lpspi_platform_info->chipselect[i];
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index be503a0e6ef7..2f75db2e75f6 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -278,14 +278,14 @@ static int spidev_message(struct spidev_data *spidev,
#ifdef VERBOSE
dev_dbg(&spidev->spi->dev,
" xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n",
- u_tmp->len,
- u_tmp->rx_buf ? "rx " : "",
- u_tmp->tx_buf ? "tx " : "",
- u_tmp->cs_change ? "cs " : "",
- u_tmp->bits_per_word ? : spidev->spi->bits_per_word,
- u_tmp->delay_usecs,
- u_tmp->word_delay_usecs,
- u_tmp->speed_hz ? : spidev->spi->max_speed_hz);
+ k_tmp->len,
+ k_tmp->rx_buf ? "rx " : "",
+ k_tmp->tx_buf ? "tx " : "",
+ k_tmp->cs_change ? "cs " : "",
+ k_tmp->bits_per_word ? : spidev->spi->bits_per_word,
+ k_tmp->delay_usecs,
+ k_tmp->word_delay_usecs,
+ k_tmp->speed_hz ? : spidev->spi->max_speed_hz);
#endif
spi_message_add_tail(k_tmp, &msg);
}
@@ -457,10 +457,11 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
spi->max_speed_hz = tmp;
retval = spi_setup(spi);
- if (retval >= 0)
+ if (retval == 0) {
spidev->speed_hz = tmp;
- else
- dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
+ dev_dbg(&spi->dev, "%d Hz (max)\n",
+ spidev->speed_hz);
+ }
spi->max_speed_hz = save;
}
break;
@@ -678,6 +679,7 @@ static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "lwn,bk4" },
{ .compatible = "dh,dhcom-board" },
{ .compatible = "menlo,m53cpld" },
+ { .compatible = "toradex,evalspi" },
{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/drivers/staging/media/imx/imx8-isi-cap.c b/drivers/staging/media/imx/imx8-isi-cap.c
index 0960a8fa8af8..3fa632290290 100644
--- a/drivers/staging/media/imx/imx8-isi-cap.c
+++ b/drivers/staging/media/imx/imx8-isi-cap.c
@@ -36,6 +36,14 @@ static int mxc_isi_cap_streamoff(struct file *file, void *priv,
struct mxc_isi_fmt mxc_isi_out_formats[] = {
{
+ .name = "UYVY-16",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = { 16 },
+ .color = MXC_ISI_OUT_FMT_YUV422_1P8P,
+ .memplanes = 1,
+ .colplanes = 1,
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+ }, {
.name = "RGB565",
.fourcc = V4L2_PIX_FMT_RGB565,
.depth = { 16 },
@@ -528,6 +536,8 @@ static struct vb2_ops mxc_cap_vb2_qops = {
.stop_streaming = cap_vb2_stop_streaming,
};
+/* To enable ctrls in sensor driver, we need to comment the ISI ctrls */
+#ifndef CONFIG_VIDEO_ECAM
/*
* V4L2 controls handling
*/
@@ -617,6 +627,7 @@ void mxc_isi_ctrls_delete(struct mxc_isi_cap_dev *isi_cap)
ctrls->alpha = NULL;
}
}
+#endif
static struct media_pad
*mxc_isi_get_remote_source_pad(struct v4l2_subdev *subdev)
@@ -1290,6 +1301,129 @@ static int mxc_isi_cap_enum_frameintervals(struct file *file, void *fh,
return 0;
}
+#ifdef CONFIG_VIDEO_ECAM
+static int mxc_vidioc_queryctrl(struct file *file, void *fh,
+ struct v4l2_queryctrl *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, queryctrl, a);
+}
+
+static int mxc_vidioc_query_ext_ctrl(struct file *file, void *fh,
+ struct v4l2_query_ext_ctrl *qec)
+{
+ struct v4l2_queryctrl qc = {
+ .id = qec->id
+ };
+ int ret;
+
+ ret = mxc_vidioc_queryctrl(file, fh, &qc);
+
+ if (ret)
+ return ret;
+
+ qec->id = qc.id;
+ qec->type = qc.type;
+ strlcpy(qec->name, qc.name, sizeof(qec->name));
+ qec->maximum = qc.maximum;
+ qec->minimum = qc.minimum;
+ qec->step = qc.step;
+ qec->default_value = qc.default_value;
+ qec->flags = qc.flags;
+ qec->elem_size = 4;
+ qec->elems = 1;
+ qec->nr_of_dims = 0;
+ memset(qec->dims, 0, sizeof(qec->dims));
+ memset(qec->reserved, 0, sizeof(qec->reserved));
+
+ return 0;
+}
+
+static int mxc_isi_vidioc_querymenu(struct file *file, void *fh,
+ struct v4l2_querymenu *qm)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, querymenu, qm);
+}
+
+static int mxc_isi_vidioc_g_ctrl(struct file *file, void *fh,
+ struct v4l2_control *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, g_ctrl, a);
+}
+
+static int mxc_isi_vidioc_s_ctrl(struct file *file, void *fh,
+ struct v4l2_control *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, s_ctrl, a);
+}
+
+static int mxc_isi_vidioc_g_ext_ctrls(struct file *file, void *fh,
+ struct v4l2_ext_controls *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, g_ext_ctrls, a);
+}
+
+static int mxc_isi_vidioc_try_ext_ctrls(struct file *file, void *fh,
+ struct v4l2_ext_controls *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, try_ext_ctrls, a);
+}
+
+static int mxc_isi_vidioc_s_ext_ctrls(struct file *file, void *fh,
+ struct v4l2_ext_controls *a)
+{
+ struct mxc_isi_cap_dev *isi_cap = video_drvdata(file);
+ struct v4l2_subdev *sd;
+
+ sd = mxc_get_remote_subdev(&isi_cap->sd, __func__);
+ if (!sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sd, core, s_ext_ctrls, a);
+}
+#endif
+
static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
.vidioc_querycap = mxc_isi_cap_querycap,
@@ -1317,6 +1451,16 @@ static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
.vidioc_enum_framesizes = mxc_isi_cap_enum_framesizes,
.vidioc_enum_frameintervals = mxc_isi_cap_enum_frameintervals,
+#ifdef CONFIG_VIDEO_ECAM
+ .vidioc_queryctrl = mxc_vidioc_queryctrl,
+ .vidioc_query_ext_ctrl = mxc_vidioc_query_ext_ctrl,
+ .vidioc_querymenu = mxc_isi_vidioc_querymenu,
+ .vidioc_g_ctrl = mxc_isi_vidioc_g_ctrl,
+ .vidioc_s_ctrl = mxc_isi_vidioc_s_ctrl,
+ .vidioc_g_ext_ctrls = mxc_isi_vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = mxc_isi_vidioc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = mxc_isi_vidioc_try_ext_ctrls
+#endif
};
/* Capture subdev media entity operations */
@@ -1633,23 +1777,29 @@ static int mxc_isi_register_cap_device(struct mxc_isi_cap_dev *isi_cap,
if (ret)
goto err_free_ctx;
+/* To enable ctrls in sensor driver, we need to comment the ISI ctrls */
+#ifndef CONFIG_VIDEO_ECAM
ret = mxc_isi_ctrls_create(isi_cap);
if (ret)
goto err_me_cleanup;
+#endif
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
if (ret)
goto err_ctrl_free;
-
+#ifndef CONFIG_VIDEO_ECAM
vdev->ctrl_handler = &isi_cap->ctrls.handler;
+#endif
v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
vdev->name, video_device_node_name(vdev));
return 0;
err_ctrl_free:
+#ifndef CONFIG_VIDEO_ECAM
mxc_isi_ctrls_delete(isi_cap);
err_me_cleanup:
+#endif
media_entity_cleanup(&vdev->entity);
err_free_ctx:
return ret;
@@ -1686,7 +1836,10 @@ static void mxc_isi_subdev_unregistered(struct v4l2_subdev *sd)
vdev = &isi_cap->vdev;
if (video_is_registered(vdev)) {
video_unregister_device(vdev);
+/* To enable ctrls in sensor driver, we need to comment the ISI ctrls*/
+#ifndef CONFIG_VIDEO_ECAM
mxc_isi_ctrls_delete(isi_cap);
+#endif
media_entity_cleanup(&vdev->entity);
}
mutex_unlock(&isi_cap->lock);
diff --git a/drivers/staging/media/imx/imx8-mipi-csi2.c b/drivers/staging/media/imx/imx8-mipi-csi2.c
index 8881a5a3596c..0227a4f25538 100644
--- a/drivers/staging/media/imx/imx8-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx8-mipi-csi2.c
@@ -813,6 +813,93 @@ static const struct media_entity_operations mipi_csi2_sd_media_ops = {
/*
* V4L2 subdev operations
*/
+#ifdef CONFIG_VIDEO_ECAM
+static int mipi_csi2_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, querymenu, qm);
+}
+
+static int mipi_csi2_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, queryctrl, qc);
+}
+
+static int mipi_csi2_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, g_ctrl, ctrl);
+}
+
+static int mipi_csi2_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, s_ctrl, ctrl);
+}
+
+static int mipi_csi2_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, g_ext_ctrls, ctrls);
+}
+
+static int mipi_csi2_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, try_ext_ctrls, ctrls);
+}
+
+static int mipi_csi2_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct v4l2_subdev *sen_sd;
+
+ sen_sd = mxc_get_remote_subdev(csi2dev, __func__);
+ if (!sen_sd)
+ return -EINVAL;
+
+ return v4l2_subdev_call(sen_sd, core, s_ext_ctrls, ctrls);
+}
+#endif
+
static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on)
{
struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
@@ -964,6 +1051,15 @@ static struct v4l2_subdev_pad_ops mipi_csi2_pad_ops = {
static struct v4l2_subdev_core_ops mipi_csi2_core_ops = {
.s_power = mipi_csi2_s_power,
+#ifdef CONFIG_VIDEO_ECAM
+ .queryctrl = mipi_csi2_queryctrl,
+ .g_ctrl = mipi_csi2_g_ctrl,
+ .s_ctrl = mipi_csi2_s_ctrl,
+ .g_ext_ctrls = mipi_csi2_g_ext_ctrls,
+ .s_ext_ctrls = mipi_csi2_s_ext_ctrls,
+ .try_ext_ctrls = mipi_csi2_try_ext_ctrls,
+ .querymenu = mipi_csi2_querymenu,
+#endif
};
static struct v4l2_subdev_video_ops mipi_csi2_video_ops = {
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 9e9f1155ac9f..8c84dacdee66 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -584,10 +584,10 @@ static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
}
/*
- * Set the critical trip point at 5 °C under max
+ * Set the critical trip point at max
* Set the passive trip point at 10 °C under max (changeable via sysfs)
*/
- data->temp_critical = data->temp_max - (1000 * 5);
+ data->temp_critical = data->temp_max;
data->temp_passive = data->temp_max - (1000 * 10);
}
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 3af0de55da9a..8f320fdcdebc 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -207,6 +207,7 @@
#define UARTMODIR_IREN 0x00020000
#define UARTMODIR_RTSWATER_S 0x8
+#define UARTMODIR_RTSWATER_M 0x0000ff00
#define UARTMODIR_TXCTSSRC 0x00000020
#define UARTMODIR_TXCTSC 0x00000010
#define UARTMODIR_RXRTSE 0x00000008
@@ -1424,6 +1425,48 @@ static void lpuart_dma_rx_free(struct uart_port *port)
sport->dma_rx_cookie = -EINVAL;
}
+static void __maybe_unused lpuart_setup_rs485(struct lpuart_port *sport)
+{
+ /* Todo implement for 8-bit registers */
+}
+
+static void lpuart32_setup_rs485(struct lpuart_port *sport)
+{
+ struct serial_rs485 *rs485 = &sport->port.rs485;
+ unsigned long val, ctrl, ctrl_saved;
+
+ val = lpuart32_read(&sport->port, UARTMODIR) &
+ ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
+
+ /* Make sure transmitter is disabled */
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ ctrl_saved = ctrl;
+ ctrl &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_TE |
+ UARTCTRL_RIE | UARTCTRL_RE);
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
+
+ if (rs485->flags & SER_RS485_ENABLED) {
+ /* Enable auto RS-485 RTS mode */
+ val |= UARTMODIR_TXRTSE;
+
+ /*
+ * The hardware defaults to RTS logic HIGH while transfer.
+ * Switch polarity in case RTS shall be logic HIGH
+ * after transfer.
+ * Note: UART is assumed to be active high.
+ */
+ if (rs485->flags & SER_RS485_RTS_ON_SEND)
+ val &= ~UARTMODIR_TXRTSPOL;
+ else if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
+ val |= UARTMODIR_TXRTSPOL;
+ }
+
+ lpuart32_write(&sport->port, val, UARTMODIR);
+
+ /* Restore cr2 */
+ lpuart32_write(&sport->port, ctrl_saved, UARTCTRL);
+}
+
static int lpuart_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
@@ -1475,6 +1518,41 @@ static int lpuart_config_rs485(struct uart_port *port,
return 0;
}
+static int lpuart32_config_rs485(struct uart_port *port,
+ struct serial_rs485 *rs485)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+
+ /* clear unsupported configurations */
+ rs485->delay_rts_before_send = 0;
+ rs485->delay_rts_after_send = 0;
+ rs485->flags &= ~SER_RS485_RX_DURING_TX;
+
+ if (rs485->flags & SER_RS485_ENABLED) {
+ /*
+ * RTS needs to be logic HIGH either during transer _or_ after
+ * transfer, other variants are not supported by the hardware.
+ */
+
+ if (!(rs485->flags & (SER_RS485_RTS_ON_SEND |
+ SER_RS485_RTS_AFTER_SEND)))
+ rs485->flags |= SER_RS485_RTS_ON_SEND;
+
+ if (rs485->flags & SER_RS485_RTS_ON_SEND &&
+ rs485->flags & SER_RS485_RTS_AFTER_SEND)
+ rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
+ }
+
+ /* Store the new configuration */
+ sport->port.rs485 = *rs485;
+
+ /* config_rs485 gets called in irqsave context so do not lock again */
+ lpuart32_setup_rs485(sport);
+
+ return 0;
+}
+
static unsigned int lpuart_get_mctrl(struct uart_port *port)
{
unsigned int temp = 0;
@@ -1636,7 +1714,8 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
val |= UARTFIFO_TXFE | UARTFIFO_RXFE;
val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
val &= ~(UARTFIFO_RXIDEN_MASK << UARTFIFO_RXIDEN_OFF);
- rxiden_cnt = sport->dma_eeop ? 0 : UARTFIFO_RXIDEN_RDRF;
+ rxiden_cnt = (sport->dma_eeop && sport->lpuart_dma_rx_use) ?
+ 0 : UARTFIFO_RXIDEN_RDRF;
val |= ((rxiden_cnt & UARTFIFO_RXIDEN_MASK) <<
UARTFIFO_RXIDEN_OFF);
lpuart32_write(&sport->port, val, UARTFIFO);
@@ -1650,8 +1729,10 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
/* set RTS watermark */
if (!uart_console(&sport->port)) {
- val = lpuart32_read(&sport->port, UARTMODIR);
- val = (sport->rxfifo_size >> 1) << UARTMODIR_RTSWATER_S;
+ val = lpuart32_read(&sport->port, UARTMODIR) &
+ ~UARTMODIR_RTSWATER_M;
+ val |= ((sport->rxfifo_size >> 1) << UARTMODIR_RTSWATER_S) &
+ UARTMODIR_RTSWATER_M;
lpuart32_write(&sport->port, val, UARTMODIR);
}
@@ -1791,6 +1872,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport)
lpuart_rx_dma_startup(sport);
lpuart_tx_dma_startup(sport);
+ lpuart32_setup_rs485(sport);
lpuart32_setup_watermark_enable(sport);
lpuart32_configure(sport);
@@ -2078,10 +2160,15 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
sbr = 0;
for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
- /* calculate the temporary sbr value */
+ /*
+ * calculate the temporary sbr value, sbr must be in 1..8191,
+ * limit to 8190, as the loop checks for sbr and sbr + 1
+ */
tmp_sbr = (clk / (baudrate * tmp_osr));
if (tmp_sbr == 0)
tmp_sbr = 1;
+ if (tmp_sbr > 8190)
+ tmp_sbr = 8190;
/*
* calculate the baud rate difference based on the temporary
@@ -2170,6 +2257,13 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
ctrl |= UARTCTRL_M;
}
+ /*
+ * When auto RS-485 RTS mode is enabled,
+ * hardware flow control need to be disabled.
+ */
+ if (sport->port.rs485.flags & SER_RS485_ENABLED)
+ termios->c_cflag &= ~CRTSCTS;
+
if (termios->c_cflag & CRTSCTS) {
modem |= UARTMODEM_RXRTSE | UARTMODEM_TXCTSE;
} else {
@@ -2716,6 +2810,7 @@ static int lpuart_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct lpuart_port *sport;
struct resource *res;
+ unsigned long flags;
int ret;
sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
@@ -2747,7 +2842,10 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.ops = &lpuart_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
- sport->port.rs485_config = lpuart_config_rs485;
+ if (lpuart_is_32(sport))
+ sport->port.rs485_config = lpuart32_config_rs485;
+ else
+ sport->port.rs485_config = lpuart_config_rs485;
ret = lpuart_attach_pd(&pdev->dev);
if (ret)
@@ -2830,7 +2928,9 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.rs485.delay_rts_after_send)
dev_err(&pdev->dev, "driver doesn't support RTS delays\n");
- lpuart_config_rs485(&sport->port, &sport->port.rs485);
+ spin_lock_irqsave(&sport->port.lock, flags);
+ sport->port.rs485_config(&sport->port, &sport->port.rs485);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index c72a7cda4638..b07224aea651 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2379,6 +2379,18 @@ static int imx_uart_probe(struct platform_device *pdev)
clk_disable_unprepare(sport->clk_ipg);
+ /* if DTE mode is requested, make sure DTE mode is selected
+ and then disable DCDDELT/RIDELT interrupts */
+ if (!imx_uart_is_imx1(sport) && sport->dte_mode) {
+ u32 ucr3, ufcr;
+ ufcr = imx_uart_readl(sport, UFCR);
+ ufcr |= UFCR_DCEDTE;
+ imx_uart_writel(sport, ufcr, UFCR);
+ ucr3 = imx_uart_readl(sport, UCR3);
+ ucr3 &= ~(UCR3_DCD | UCR3_RI);
+ imx_uart_writel(sport, ucr3, UCR3);
+ }
+
/*
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later
* chips only have one interrupt.
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 6b3caf9dcd96..64f11388d2e9 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -175,6 +175,7 @@ struct hw_bank {
* @enabled_otg_timer_bits: bits of enabled otg timers
* @next_otg_timer: next nearest enabled timer to be expired
* @work: work for role changing
+ * @work_dr: work for role changing for non-OTG controllers
* @wq: workqueue thread
* @qh_pool: allocation pool for queue heads
* @td_pool: allocation pool for transfer descriptors
@@ -228,6 +229,7 @@ struct ci_hdrc {
enum otg_fsm_timer next_otg_timer;
struct usb_role_switch *role_switch;
struct work_struct work;
+ struct work_struct work_dr;
struct workqueue_struct *wq;
struct dma_pool *qh_pool;
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 1206c5762bd6..61e6cc29488a 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -594,6 +594,47 @@ static irqreturn_t ci_irq_handler(int irq, void *data)
return ret;
}
+static void usb_roleswitch_workqueue(struct work_struct *work)
+{
+ struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work_dr);
+ struct ci_hdrc_cable *id, *vbus;
+ int ret;
+
+ pm_runtime_get_sync(ci->dev);
+
+ id = &ci->platdata->id_extcon;
+ if (!IS_ERR(id->edev)) {
+ int new_role;
+
+ ci_role_stop(ci);
+ hw_wait_phy_stable();
+
+ ret = extcon_get_state(id->edev, EXTCON_USB_HOST);
+ if (ret) {
+ new_role = CI_ROLE_HOST;
+ dev_info(ci->dev, "switching to host role\n");
+ } else {
+ new_role = CI_ROLE_GADGET;
+ dev_info(ci->dev, "switching to gadget role\n");
+ }
+ ci_role_start(ci, new_role);
+ }
+
+ vbus = &ci->platdata->vbus_extcon;
+ if (!IS_ERR(vbus->edev)) {
+ ret = extcon_get_state(vbus->edev, EXTCON_USB);
+ if (ret) {
+ usb_gadget_vbus_connect(&ci->gadget);
+ } else {
+ usb_gadget_vbus_disconnect(&ci->gadget);
+ }
+ }
+
+ pm_runtime_put_sync(ci->dev);
+
+ enable_irq(ci->irq);
+}
+
static void ci_irq(struct ci_hdrc *ci)
{
unsigned long flags;
@@ -609,10 +650,24 @@ static int ci_cable_notifier(struct notifier_block *nb, unsigned long event,
struct ci_hdrc_cable *cbl = container_of(nb, struct ci_hdrc_cable, nb);
struct ci_hdrc *ci = cbl->ci;
- cbl->connected = event;
- cbl->changed = true;
+ if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG) {
+ disable_irq_nosync(ci->irq);
+
+ /*
+ * This notifier might get called twice in succession,
+ * once for the ID pin and once for the VBUS pin. Make
+ * sure we only disable irq in case we successfully add
+ * work to the work queue.
+ */
+ if (!queue_work(system_power_efficient_wq, &ci->work_dr))
+ enable_irq(ci->irq);
+ } else {
+ cbl->connected = event;
+ cbl->changed = true;
+
+ ci_irq(ci);
+ }
- ci_irq(ci);
return NOTIFY_DONE;
}
@@ -783,6 +838,7 @@ static int ci_get_platdata(struct device *dev,
ext_id = extcon_get_edev_by_phandle(dev, 1);
if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
return PTR_ERR(ext_id);
+ platdata->flags |= CI_HDRC_DUAL_ROLE_NOT_OTG;
}
cable = &platdata->vbus_extcon;
@@ -1033,6 +1089,13 @@ static enum ci_role ci_get_role(struct ci_hdrc *ci)
* role switch, the defalt role is gadget, and the
* user can switch it through debugfs.
*/
+ struct ci_hdrc_cable *id = &ci->platdata->id_extcon;
+ if (!IS_ERR(id->edev)) {
+ if (extcon_get_state(id->edev, EXTCON_USB_HOST))
+ return CI_ROLE_HOST;
+ else
+ return CI_ROLE_GADGET;
+ }
return CI_ROLE_GADGET;
}
} else {
@@ -1174,7 +1237,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
ci_get_otg_capable(ci);
+ if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG)
+ INIT_WORK(&ci->work_dr, usb_roleswitch_workqueue);
+
+ ret = ci_extcon_register(ci);
+ if (ret)
+ goto stop;
+
dr_mode = ci->platdata->dr_mode;
+
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
ret = ci_hdrc_host_init(ci);
@@ -1247,6 +1318,21 @@ static int ci_hdrc_probe(struct platform_device *pdev)
}
if (!ci_otg_is_fsm_mode(ci)) {
+
+ /* only update vbus status for peripheral */
+ if (dr_mode == USB_DR_MODE_PERIPHERAL) {
+ usb_gadget_vbus_connect(&ci->gadget);
+ } else if (ci->role == CI_ROLE_GADGET) {
+ struct ci_hdrc_cable *vbus = &ci->platdata->vbus_extcon;
+
+ /* Use vbus state from extcon if provided */
+ if (!IS_ERR(vbus->edev) &&
+ extcon_get_state(vbus->edev, EXTCON_USB))
+ usb_gadget_vbus_connect(&ci->gadget);
+ else
+ ci_handle_vbus_change(ci);
+ }
+
ret = ci_role_start(ci, ci->role);
if (ret) {
dev_err(dev, "can't start %s role\n",
@@ -1260,10 +1346,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto stop;
- ret = ci_extcon_register(ci);
- if (ret)
- goto stop;
-
if (ci->supports_runtime_pm) {
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
index 72f39a9751b5..83f7c80b760d 100644
--- a/drivers/usb/misc/usb3503.c
+++ b/drivers/usb/misc/usb3503.c
@@ -46,7 +46,9 @@ struct usb3503 {
struct regmap *regmap;
struct device *dev;
struct clk *clk;
+ u8 port_nrd;
u8 port_off_mask;
+ int gpio_bypass;
int gpio_intn;
int gpio_reset;
int gpio_connect;
@@ -61,6 +63,9 @@ static int usb3503_reset(struct usb3503 *hub, int state)
if (gpio_is_valid(hub->gpio_reset))
gpio_set_value_cansleep(hub->gpio_reset, state);
+ if (gpio_is_valid(hub->gpio_bypass))
+ gpio_set_value_cansleep(hub->gpio_bypass, state);
+
/* Wait T_HUBINIT == 4ms for hub logic to stabilize */
if (state)
usleep_range(4000, 10000);
@@ -87,8 +92,7 @@ static int usb3503_connect(struct usb3503 *hub)
/* PDS : Set the ports which are disabled in self-powered mode. */
if (hub->port_off_mask) {
- err = regmap_update_bits(hub->regmap, USB3503_PDS,
- hub->port_off_mask,
+ err = regmap_write(hub->regmap, USB3503_PDS,
hub->port_off_mask);
if (err < 0) {
dev_err(dev, "PDS failed (%d)\n", err);
@@ -105,12 +109,22 @@ static int usb3503_connect(struct usb3503 *hub)
return err;
}
+ /* NRD : Set non removable ports. */
+ if (hub->port_nrd) {
+ err = regmap_write(hub->regmap, USB3503_NRD,
+ hub->port_nrd);
+ if (err < 0) {
+ dev_err(dev, "NRD failed (%d)\n", err);
+ return err;
+ }
+ }
+
/* SP_LOCK: clear connect_n, config_n for hub connect */
err = regmap_update_bits(hub->regmap, USB3503_SP_ILOCK,
(USB3503_SPILOCK_CONNECT
| USB3503_SPILOCK_CONFIG), 0);
if (err < 0) {
- dev_err(dev, "SP_ILOCK failed (%d)\n", err);
+ dev_err(dev, "SP_ILOCK 2 failed (%d)\n", err);
return err;
}
}
@@ -166,7 +180,9 @@ static int usb3503_probe(struct usb3503 *hub)
int len;
if (pdata) {
+ hub->port_nrd = pdata->port_nrd;
hub->port_off_mask = pdata->port_off_mask;
+ hub->gpio_bypass = pdata->gpio_bypass;
hub->gpio_intn = pdata->gpio_intn;
hub->gpio_connect = pdata->gpio_connect;
hub->gpio_reset = pdata->gpio_reset;
@@ -225,17 +241,32 @@ static int usb3503_probe(struct usb3503 *hub)
int i;
for (i = 0; i < len / sizeof(u32); i++) {
u32 port = be32_to_cpu(property[i]);
+ dev_dbg(dev, "disabled-ports, port: %d\n", port);
if ((1 <= port) && (port <= 3))
hub->port_off_mask |= (1 << port);
}
}
+ property = of_get_property(np, "non-removable-devices", &len);
+ if (property && (len / sizeof(u32)) > 0) {
+ int i;
+ for (i = 0; i < len / sizeof(u32); i++) {
+ u32 port = be32_to_cpu(property[i]);
+ dev_dbg(dev, "non-removable-devices, port: %d\n", port);
+ if ((1 <= port) && (port <= 3))
+ hub->port_nrd |= (1 << port);
+ }
+ }
+
hub->gpio_intn = of_get_named_gpio(np, "intn-gpios", 0);
if (hub->gpio_intn == -EPROBE_DEFER)
return -EPROBE_DEFER;
hub->gpio_connect = of_get_named_gpio(np, "connect-gpios", 0);
if (hub->gpio_connect == -EPROBE_DEFER)
return -EPROBE_DEFER;
+ hub->gpio_bypass = of_get_named_gpio(np, "bypass-gpios", 0);
+ if (hub->gpio_bypass == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0);
if (hub->gpio_reset == -EPROBE_DEFER)
return -EPROBE_DEFER;
@@ -270,6 +301,17 @@ static int usb3503_probe(struct usb3503 *hub)
}
}
+ if (gpio_is_valid(hub->gpio_bypass)) {
+ err = devm_gpio_request_one(dev, hub->gpio_bypass,
+ GPIOF_OUT_INIT_LOW, "usb3503 bypass");
+ if (err) {
+ dev_err(dev,
+ "unable to request GPIO %d as bypass pin (%d)\n",
+ hub->gpio_bypass, err);
+ return err;
+ }
+ }
+
if (gpio_is_valid(hub->gpio_reset)) {
err = devm_gpio_request_one(dev, hub->gpio_reset,
GPIOF_OUT_INIT_LOW, "usb3503 reset");
@@ -404,6 +446,7 @@ MODULE_DEVICE_TABLE(i2c, usb3503_id);
static const struct of_device_id usb3503_of_match[] = {
{ .compatible = "smsc,usb3503", },
{ .compatible = "smsc,usb3503a", },
+ { .compatible = "smsc,usb3803", },
{},
};
MODULE_DEVICE_TABLE(of, usb3503_of_match);
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index a53b89be5324..5c39a2644b5c 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -44,30 +44,37 @@ void usb_phy_generic_unregister(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(usb_phy_generic_unregister);
-static int nop_set_suspend(struct usb_phy *x, int suspend)
-{
- struct usb_phy_generic *nop = dev_get_drvdata(x->dev);
-
- if (!IS_ERR(nop->clk)) {
- if (suspend)
- clk_disable_unprepare(nop->clk);
- else
- clk_prepare_enable(nop->clk);
- }
-
- return 0;
-}
-
static void nop_reset(struct usb_phy_generic *nop)
{
if (!nop->gpiod_reset)
return;
+ dev_dbg(nop->dev, "reset\n");
+
gpiod_set_value_cansleep(nop->gpiod_reset, 1);
usleep_range(10000, 20000);
gpiod_set_value_cansleep(nop->gpiod_reset, 0);
}
+static int nop_set_suspend(struct usb_phy *x, int suspend)
+{
+ struct usb_phy_generic *nop = dev_get_drvdata(x->dev);
+
+ dev_dbg(x->dev, "%s\n", suspend ? "suspend" : "resume");
+
+ if (suspend) {
+ if (!IS_ERR(nop->clk))
+ clk_disable_unprepare(nop->clk);
+ } else {
+ if (!IS_ERR(nop->clk))
+ clk_prepare_enable(nop->clk);
+
+ if (nop->reset_on_resume)
+ nop_reset(nop);
+ }
+ return 0;
+}
+
/* interface to regulator framework */
static void nop_set_vbus_draw(struct usb_phy_generic *nop, unsigned mA)
{
@@ -219,6 +226,9 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop,
if (of_property_read_u32(node, "clock-frequency", &clk_rate))
clk_rate = 0;
+ nop->reset_on_resume =
+ of_property_read_bool(node, "reset-on-resume");
+
needs_vcc = of_property_read_bool(node, "vcc-supply");
needs_clk = of_property_read_bool(node, "clocks");
nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
@@ -229,6 +239,8 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop,
"vbus-detect",
GPIOD_ASIS);
err = PTR_ERR_OR_ZERO(nop->gpiod_vbus);
+ } else {
+ nop->gpiod_reset = NULL;
}
} else if (pdata) {
type = pdata->type;
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h
index 97289627561d..9ddca95fad33 100644
--- a/drivers/usb/phy/phy-generic.h
+++ b/drivers/usb/phy/phy-generic.h
@@ -15,6 +15,7 @@ struct usb_phy_generic {
struct gpio_desc *gpiod_vbus;
struct regulator *vbus_draw;
bool vbus_draw_enabled;
+ bool reset_on_resume;
unsigned long mA;
unsigned int vbus;
};
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index e77d654791b4..9c4be5c5af14 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -470,7 +470,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
* assume that another driver will enable the backlight at the
* appropriate time. Therefore, if it is disabled, keep it so.
*/
- return active ? FB_BLANK_UNBLANK: FB_BLANK_POWERDOWN;
+ return FB_BLANK_UNBLANK;
}
static int pwm_backlight_probe(struct platform_device *pdev)
diff --git a/drivers/video/fbdev/mxc/Makefile b/drivers/video/fbdev/mxc/Makefile
index 6addd0b3a05d..80397a6519a8 100644
--- a/drivers/video/fbdev/mxc/Makefile
+++ b/drivers/video/fbdev/mxc/Makefile
@@ -12,6 +12,6 @@ obj-$(CONFIG_FB_MXC_LDB) += ldb.o
obj-$(CONFIG_FB_MXS_SII902X) += mxsfb_sii902x.o mxsfb_sii902x_audio.o
obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o
obj-$(CONFIG_FB_MXC_DCIC) += mxc_dcic.o
-obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_lcdif.o mxc_ipuv3_fb.o
+obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_lcdif.o mxc_vdacif.o mxc_ipuv3_fb.o
obj-$(CONFIG_FB_MXC_EINK_PANEL) += mxc_epdc_fb.o
obj-$(CONFIG_FB_MXC_EINK_V2_PANEL) += mxc_epdc_v2_fb.o
diff --git a/drivers/video/fbdev/mxc/ldb.c b/drivers/video/fbdev/mxc/ldb.c
index 1d6c9e08590c..66a8fe51a84d 100644
--- a/drivers/video/fbdev/mxc/ldb.c
+++ b/drivers/video/fbdev/mxc/ldb.c
@@ -22,6 +22,7 @@
#include <linux/regmap.h>
#include <linux/types.h>
#include <video/of_videomode.h>
+#include <video/of_display_timing.h>
#include <video/videomode.h>
#include "mxc_dispdrv.h"
@@ -77,7 +78,8 @@ struct ldb_data;
struct ldb_chan {
struct ldb_data *ldb;
struct fb_info *fbi;
- struct videomode vm;
+ unsigned long serial_clk;
+ struct display_timings *timings;
enum crtc crtc;
int chno;
bool is_used;
@@ -301,8 +303,10 @@ static int ldb_init(struct mxc_dispdrv_handle *mddh,
struct device *dev = ldb->dev;
struct fb_info *fbi = setting->fbi;
struct ldb_chan *chan;
- struct fb_videomode fb_vm;
- int chno;
+ struct fb_videomode fb_vm, native_mode;
+ int chno, i, ret;
+ struct videomode vm;
+ unsigned long pixelclock;
chno = ldb->chan[ldb->primary_chno].is_used ?
!ldb->primary_chno : ldb->primary_chno;
@@ -322,10 +326,40 @@ static int ldb_init(struct mxc_dispdrv_handle *mddh,
chan->fbi = fbi;
- fb_videomode_from_videomode(&chan->vm, &fb_vm);
- fb_videomode_to_var(&fbi->var, &fb_vm);
-
setting->crtc = chan->crtc;
+
+ INIT_LIST_HEAD(&fbi->modelist);
+ for (i = 0; i < chan->timings->num_timings; i++) {
+ ret = videomode_from_timings(chan->timings, &vm, i);
+ if (ret < 0) {
+ dev_err(ldb->dev,
+ "failed to get video mode from timings\n");
+ return ret;
+ }
+
+ ret = fb_videomode_from_videomode(&vm, &fb_vm);
+ if (ret < 0) {
+ dev_err(ldb->dev,
+ "failed to get fb video mode from video mode\n");
+ return ret;
+ }
+
+ if (i == chan->timings->native_mode)
+ fb_videomode_from_videomode(&vm, &native_mode);
+
+ fb_add_videomode(&fb_vm, &fbi->modelist);
+ fb_videomode_to_var(&fbi->var, &fb_vm);
+ }
+
+ fb_find_mode(&fbi->var, fbi, setting->dft_mode_str, &fb_vm,
+ chan->timings->num_timings, &native_mode,
+ setting->default_bpp);
+
+ /* Calculate the LVDS clock */
+ fb_var_to_videomode(&fb_vm, &fbi->var);
+
+ pixelclock = fb_vm.pixclock ? (1000000000UL/(fb_vm.pixclock)) * 1000: 0;
+ chan->serial_clk = ldb->spl_mode ? pixelclock * 7 / 2 : pixelclock * 7;
return 0;
}
@@ -399,7 +433,6 @@ static int ldb_setup(struct mxc_dispdrv_handle *mddh,
struct clk *other_ldb_di_sel = NULL;
struct bus_mux bus_mux;
int ret = 0, id = 0, chno, other_chno;
- unsigned long serial_clk;
u32 mux_val;
ret = find_ldb_chno(ldb, fbi, &chno);
@@ -453,9 +486,7 @@ static int ldb_setup(struct mxc_dispdrv_handle *mddh,
clk_set_parent(ldb->div_sel_clk[chno], ldb_di_parent);
ldb_di_sel = clk_get_parent(ldb_di_parent);
ldb_di_sel_parent = clk_get_parent(ldb_di_sel);
- serial_clk = ldb->spl_mode ? chan.vm.pixelclock * 7 / 2 :
- chan.vm.pixelclock * 7;
- clk_set_rate(ldb_di_sel_parent, serial_clk);
+ clk_set_rate(ldb_di_sel_parent, chan.serial_clk);
/*
* split mode or dual mode:
@@ -834,9 +865,11 @@ static int ldb_probe(struct platform_device *pdev)
return -EINVAL;
}
- ret = of_get_videomode(child, &chan->vm, 0);
- if (ret)
- return -EINVAL;
+ chan->timings = of_get_display_timings(child);
+ if (!chan->timings) {
+ dev_err(ldb->dev, "failed to get display timings\n");
+ ret = -ENOENT;
+ }
sprintf(clkname, "ldb_di%d", i);
ldb->ldb_di_clk[i] = devm_clk_get(dev, clkname);
diff --git a/drivers/video/fbdev/mxc/mxc_hdmi.c b/drivers/video/fbdev/mxc/mxc_hdmi.c
index 708a37cd56f5..f7ce8edf4041 100644
--- a/drivers/video/fbdev/mxc/mxc_hdmi.c
+++ b/drivers/video/fbdev/mxc/mxc_hdmi.c
@@ -73,6 +73,18 @@
#define YCBCR422_8BITS 3
#define XVYCC444 4
+static bool only_cea;
+module_param(only_cea, bool, 0644);
+MODULE_PARM_DESC(only_cea, "Allow only CEA modes");
+
+#if 0
+/* rely solely on the HPD pin for hot plug detection */
+#undef HDMI_DVI_STAT
+#define HDMI_DVI_STAT 2
+
+#undef HDMI_DVI_IH_STAT
+#define HDMI_DVI_IH_STAT 1
+#endif
/*
* We follow a flowchart which is in the "Synopsys DesignWare Courses
* HDMI Transmitter Controller User Guide, 1.30a", section 3.1
@@ -163,11 +175,11 @@ struct mxc_hdmi {
bool dft_mode_set;
char *dft_mode_str;
int default_bpp;
- u8 latest_intr_stat;
bool irq_enabled;
spinlock_t irq_lock;
bool phy_enabled;
struct fb_videomode default_mode;
+ struct fb_videomode previous_mode;
struct fb_videomode previous_non_vga_mode;
bool requesting_vga_for_initialization;
@@ -946,6 +958,9 @@ static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
return data;
}
+static int keepalive=1;
+module_param(keepalive, int, 0644);
+MODULE_PARM_DESC(keepalive, "Keep HDMI alive (don't detect disconnect)");
/* "Power-down enable (active low)"
* That mean that power up == 1! */
@@ -1284,6 +1299,8 @@ static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
}
hdmi->phy_enabled = true;
+ if (!hdmi->hdmi_data.video_mode.mDVI)
+ hdmi_enable_overflow_interrupts();
}
static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
@@ -1805,7 +1822,7 @@ static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
mode = &hdmi->fbi->monspecs.modedb[i];
if (!(mode->vmode & FB_VMODE_INTERLACED) &&
- (mxc_edid_mode_to_vic(mode) != 0)) {
+ (!only_cea || mxc_edid_mode_to_vic(mode))) {
dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
dev_dbg(&hdmi->pdev->dev,
@@ -1953,8 +1970,9 @@ static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
mxc_hdmi_edid_rebuild_modelist(hdmi);
break;
- /* Nothing to do if EDID same */
+ /* Rebuild even if they're the same in case only_cea changed */
case HDMI_EDID_SAME:
+ mxc_hdmi_edid_rebuild_modelist(hdmi);
break;
case HDMI_EDID_FAIL:
@@ -2007,74 +2025,70 @@ static void hotplug_worker(struct work_struct *work)
struct delayed_work *delay_work = to_delayed_work(work);
struct mxc_hdmi *hdmi =
container_of(delay_work, struct mxc_hdmi, hotplug_work);
- u32 phy_int_stat, phy_int_pol, phy_int_mask;
- u8 val;
+ u32 hdmi_phy_stat0, hdmi_phy_pol0, hdmi_phy_mask0;
unsigned long flags;
char event_string[32];
+ int isalive = 0;
char *envp[] = { event_string, NULL };
- phy_int_stat = hdmi->latest_intr_stat;
- phy_int_pol = hdmi_readb(HDMI_PHY_POL0);
- dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n",
- phy_int_stat, phy_int_pol);
+ hdmi_phy_stat0 = hdmi_readb(HDMI_PHY_STAT0);
+ hdmi_phy_pol0 = hdmi_readb(HDMI_PHY_POL0);
+
+ dev_dbg(&hdmi->pdev->dev, "hdmi_phy_stat0=0x%x, hdmi_phy_pol0=0x%x\n",
+ hdmi_phy_stat0, hdmi_phy_pol0);
+
+ /* Make HPD intr active low to capture unplug event or
+ * active high to capture plugin event */
+ hdmi_writeb((HDMI_DVI_STAT & ~hdmi_phy_stat0), HDMI_PHY_POL0);
/* check cable status */
- if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) {
- /* cable connection changes */
- if (phy_int_pol & HDMI_PHY_HPD) {
- /* Plugin event */
- dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
- mxc_hdmi_cable_connected(hdmi);
-
- /* Make HPD intr active low to capture unplug event */
- val = hdmi_readb(HDMI_PHY_POL0);
- val &= ~HDMI_PHY_HPD;
- hdmi_writeb(val, HDMI_PHY_POL0);
-
- hdmi_set_cable_state(1);
-
- sprintf(event_string, "EVENT=plugin");
- kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
-#ifdef CONFIG_MXC_HDMI_CEC
- mxc_hdmi_cec_handle(0x80);
-#endif
- } else if (!(phy_int_pol & HDMI_PHY_HPD)) {
- /* Plugout event */
- dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
- hdmi_set_cable_state(0);
- mxc_hdmi_abort_stream();
- mxc_hdmi_cable_disconnected(hdmi);
+ if (hdmi_phy_stat0 & HDMI_DVI_STAT) {
+ /* Plugin event */
+ dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
+ mxc_hdmi_cable_connected(hdmi);
- /* Make HPD intr active high to capture plugin event */
- val = hdmi_readb(HDMI_PHY_POL0);
- val |= HDMI_PHY_HPD;
- hdmi_writeb(val, HDMI_PHY_POL0);
+ hdmi_set_cable_state(1);
- sprintf(event_string, "EVENT=plugout");
- kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+ sprintf(event_string, "EVENT=plugin");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_MXC_HDMI_CEC
+ mxc_hdmi_cec_handle(0x80);
+#endif
+ if (keepalive)
+ hdmi_writeb(HDMI_DVI_STAT, HDMI_PHY_POL0);
+ isalive=1;
+ } else if (!keepalive) {
+ /* Plugout event */
+ dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
+ hdmi_set_cable_state(0);
+ mxc_hdmi_abort_stream();
+ mxc_hdmi_cable_disconnected(hdmi);
+
+ sprintf(event_string, "EVENT=plugout");
+ kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
#ifdef CONFIG_MXC_HDMI_CEC
- mxc_hdmi_cec_handle(0x100);
+ mxc_hdmi_cec_handle(0x100);
#endif
- } else
- dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n");
}
/* Lock here to ensure full powerdown sequence
* completed before next interrupt processed */
spin_lock_irqsave(&hdmi->irq_lock, flags);
- /* Re-enable HPD interrupts */
- phy_int_mask = hdmi_readb(HDMI_PHY_MASK0);
- phy_int_mask &= ~HDMI_PHY_HPD;
- hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0);
+ if (!(keepalive && isalive)) {
+ /* Re-enable HPD interrupts */
+ hdmi_phy_mask0 = hdmi_readb(HDMI_PHY_MASK0);
+ hdmi_phy_mask0 &= ~HDMI_DVI_STAT;
+ hdmi_writeb(hdmi_phy_mask0, HDMI_PHY_MASK0);
- /* Unmute interrupts */
- hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+ /* Unmute interrupts */
+ hdmi_writeb(~HDMI_DVI_IH_STAT, HDMI_IH_MUTE_PHY_STAT0);
- if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
- mxc_hdmi_clear_overflow(hdmi);
+ if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
+ mxc_hdmi_clear_overflow(hdmi);
+ }
spin_unlock_irqrestore(&hdmi->irq_lock, flags);
}
@@ -2097,7 +2111,7 @@ static void hdcp_hdp_worker(struct work_struct *work)
static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
{
struct mxc_hdmi *hdmi = data;
- u8 val, intr_stat;
+ u8 val;
unsigned long flags;
spin_lock_irqsave(&hdmi->irq_lock, flags);
@@ -2119,25 +2133,22 @@ static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
* HDMI registers.
*/
/* Capture status - used in hotplug_worker ISR */
- intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
-
- if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+ if (hdmi_readb(HDMI_IH_PHY_STAT0) & HDMI_DVI_IH_STAT) {
dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
- hdmi->latest_intr_stat = intr_stat;
/* Mute interrupts until handled */
val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
- val |= HDMI_IH_MUTE_PHY_STAT0_HPD;
+ val |= HDMI_DVI_IH_STAT;
hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
val = hdmi_readb(HDMI_PHY_MASK0);
- val |= HDMI_PHY_HPD;
+ val |= HDMI_DVI_STAT;
hdmi_writeb(val, HDMI_PHY_MASK0);
/* Clear Hotplug interrupts */
- hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);
schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20));
}
@@ -2169,6 +2180,9 @@ static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
+ /* Save mode as 'previous_mode' so that we can know if mode changed. */
+ memcpy(&hdmi->previous_mode, &m, sizeof(struct fb_videomode));
+
hdmi->vic = 0;
if (!hdmi->requesting_vga_for_initialization) {
/* Save mode if this isn't the result of requesting
@@ -2293,13 +2307,13 @@ static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
HDMI_PHY_I2CM_CTLINT_ADDR);
/* enable cable hot plug irq */
- hdmi_writeb((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+ hdmi_writeb((u8)~HDMI_DVI_STAT, HDMI_PHY_MASK0);
/* Clear Hotplug interrupts */
- hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);
/* Unmute interrupts */
- hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+ hdmi_writeb(~HDMI_DVI_IH_STAT, HDMI_IH_MUTE_PHY_STAT0);
hdmi->fb_reg = true;
@@ -2312,6 +2326,7 @@ static int mxc_hdmi_fb_event(struct notifier_block *nb,
{
struct fb_event *event = v;
struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
+ struct fb_videomode *mode;
if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
return 0;
@@ -2332,7 +2347,10 @@ static int mxc_hdmi_fb_event(struct notifier_block *nb,
case FB_EVENT_MODE_CHANGE:
dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
- if (hdmi->fb_reg)
+ mode = (struct fb_videomode *)event->data;
+ if ((hdmi->fb_reg) &&
+ (mode != NULL) &&
+ !fb_mode_is_equal(&hdmi->previous_mode, mode))
mxc_hdmi_setup(hdmi, val);
break;
@@ -2631,10 +2649,10 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
/* Configure registers related to HDMI interrupt
* generation before registering IRQ. */
- hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0);
+ hdmi_writeb(HDMI_DVI_STAT, HDMI_PHY_POL0);
/* Clear Hotplug interrupts */
- hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(HDMI_DVI_IH_STAT, HDMI_IH_PHY_STAT0);
hdmi->nb.notifier_call = mxc_hdmi_fb_event;
ret = fb_register_client(&hdmi->nb);
diff --git a/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c b/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
index 5c32176bfe6f..d928a621207e 100644
--- a/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
@@ -1321,6 +1321,15 @@ static int mxcfb_set_par(struct fb_info *fbi)
dev_dbg(fbi->device, "pixclock = %ul Hz\n",
(u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
+ dev_info(fbi->device,"%dx%d h_sync,r,l: %d,%d,%d v_sync,l,u: %d,%d,%d pixclock=%u Hz\n",
+ fbi->var.xres, fbi->var.yres,
+ fbi->var.hsync_len,
+ fbi->var.right_margin,
+ fbi->var.left_margin,
+ fbi->var.vsync_len,
+ fbi->var.lower_margin,
+ fbi->var.upper_margin,
+ (u32)(PICOS2KHZ(fbi->var.pixclock) * 1000UL));
if (ipu_init_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di,
(PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
@@ -3055,6 +3064,10 @@ static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
name[5] += pdev->id;
if (fb_get_options(name, &options)) {
+ if (options && !strncmp(options, "off", 3)) {
+ dev_info(&pdev->dev, "%s is turned off!\n", name);
+ return -ENODEV;
+ }
dev_err(&pdev->dev, "Can't get fb option for %s!\n", name);
return -ENODEV;
}
@@ -3133,8 +3146,7 @@ static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
fb_mode_str = opt;
}
- if (fb_mode_str)
- pdata->mode_str = fb_mode_str;
+ pdata->mode_str = fb_mode_str;
return 0;
}
@@ -3348,8 +3360,10 @@ static void mxcfb_unsetup_overlay(struct fb_info *fbi_bg)
}
static bool ipu_usage[2][2];
-static int ipu_test_set_usage(int ipu, int di)
+static int ipu_test_set_usage(unsigned ipu, unsigned di)
{
+ if ((ipu >= 2) || (di >= 2))
+ return -EINVAL;
if (ipu_usage[ipu][di])
return -EBUSY;
else
@@ -3359,6 +3373,8 @@ static int ipu_test_set_usage(int ipu, int di)
static void ipu_clear_usage(int ipu, int di)
{
+ if ((ipu >= 2) || (di >= 2))
+ return;
ipu_usage[ipu][di] = false;
}
@@ -3530,7 +3546,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
mxcfbi->ipu_ch = MEM_BG_SYNC;
/* Unblank the primary fb only by default */
- if (pdev->id == 0)
+ if (1) //(pdev->id == 0)
mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
else
mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
@@ -3571,7 +3587,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
mxcfbi->ipu_alp_ch_irq = -1;
mxcfbi->ipu_ch = MEM_DC_SYNC;
- mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
+ mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
ret = mxcfb_register(fbi);
if (ret < 0)
diff --git a/drivers/video/fbdev/mxc/mxc_lcdif.c b/drivers/video/fbdev/mxc/mxc_lcdif.c
index 83ef06322b11..f20e15c99198 100644
--- a/drivers/video/fbdev/mxc/mxc_lcdif.c
+++ b/drivers/video/fbdev/mxc/mxc_lcdif.c
@@ -49,6 +49,12 @@ static struct fb_videomode lcdif_modedb[] = {
FB_SYNC_CLK_LAT_FALL,
FB_VMODE_NONINTERLACED,
0,},
+ {
+ /* 800x480 @ 60 Hz , pixel clk @ 32MHz, neg clk pol */
+ "EDT-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
+ 0,
+ FB_VMODE_NONINTERLACED,
+ 0,},
};
static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
diff --git a/drivers/video/fbdev/mxc/mxc_vdacif.c b/drivers/video/fbdev/mxc/mxc_vdacif.c
new file mode 100644
index 000000000000..873c02a4ef51
--- /dev/null
+++ b/drivers/video/fbdev/mxc/mxc_vdacif.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2014-2016 Toradex AG. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * copy of mxc_lcdif.c
+ * adds a second parallel output which drives a Video DAC
+ * available on the second IPU, first DI on a
+ * Apalis iMX6 module
+ */
+
+#include <linux/init.h>
+#include <linux/ipu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mxcfb.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+
+#include "mxc_dispdrv.h"
+
+struct mxc_vdac_platform_data {
+ u32 default_ifmt;
+ u32 ipu_id;
+ u32 disp_id;
+};
+
+struct mxc_vdacif_data {
+ struct platform_device *pdev;
+ struct mxc_dispdrv_handle *disp_vdacif;
+};
+
+#define DISPDRV_LCD "vdac"
+
+static struct fb_videomode vdacif_modedb[] = {
+ /* 0 640x350-85 VESA */
+ { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA},
+ /* 1 640x400-85 VESA */
+ { NULL, 85, 640, 400, 31746, 96, 32, 41, 01, 64, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA },
+ /* 2 720x400-85 VESA */
+ { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA },
+ /* 3 640x480-60 VESA */
+ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 4 640x480-72 VESA */
+ { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 5 640x480-75 VESA */
+ { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 6 640x480-85 VESA */
+ { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 7 800x600-56 VESA */
+ { NULL, 56, 800, 600, 27777, 128, 24, 22, 01, 72, 2,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 8 800x600-60 VESA */
+ { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 9 800x600-72 VESA */
+ { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 10 800x600-75 VESA */
+ { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 11 800x600-85 VESA */
+ { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 12 1024x768i-43 VESA */
+ { NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_INTERLACED, FB_MODE_IS_VESA },
+ /* 13 1024x768-60 VESA */
+ { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 14 1024x768-70 VESA */
+ { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
+ FB_SYNC_OE_LOW_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 15 1024x768-75 VESA */
+ { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 16 1024x768-85 VESA */
+ { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 17 1152x864-75 VESA */
+ { NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 18 1280x960-60 VESA */
+ { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 19 1280x960-85 VESA */
+ { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 20 1280x1024-60 VESA */
+ { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 21 1280x1024-75 VESA */
+ { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 22 1280x1024-85 VESA */
+ { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 23 1600x1200-60 VESA */
+ { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 24 1600x1200-65 VESA */
+ { NULL, 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 25 1600x1200-70 VESA */
+ { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 26 1600x1200-75 VESA */
+ { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 27 1600x1200-85 VESA */
+ { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 28 1792x1344-60 VESA */
+ { NULL, 60, 1792, 1344, 4882, 328, 128, 46, 1, 200, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 29 1792x1344-75 VESA */
+ { NULL, 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 30 1856x1392-60 VESA */
+ { NULL, 60, 1856, 1392, 4580, 352, 96, 43, 1, 224, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 31 1856x1392-75 VESA */
+ { NULL, 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 32 1920x1440-60 VESA */
+ { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 33 1920x1440-75 VESA */
+ { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
+ { NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED },
+ /* #16: 1920x1080p@60Hz 16:9 */
+ { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_LOW_ACT,
+ FB_VMODE_NONINTERLACED, 0 },
+};
+static int vdacif_modedb_sz = ARRAY_SIZE(vdacif_modedb);
+
+static int vdacif_init(struct mxc_dispdrv_handle *disp,
+ struct mxc_dispdrv_setting *setting)
+{
+ int ret, i;
+ struct mxc_vdacif_data *vdacif = mxc_dispdrv_getdata(disp);
+ struct device *dev = &vdacif->pdev->dev;
+ struct mxc_vdac_platform_data *plat_data = dev->platform_data;
+ struct fb_videomode *modedb = vdacif_modedb;
+ int modedb_sz = vdacif_modedb_sz;
+
+ /* use platform defined ipu/di */
+ ret = ipu_di_to_crtc(dev, plat_data->ipu_id,
+ plat_data->disp_id, &setting->crtc);
+ if (ret < 0)
+ return ret;
+
+ ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
+ modedb, modedb_sz, NULL, setting->default_bpp);
+ if (!ret) {
+ fb_videomode_to_var(&setting->fbi->var, &modedb[0]);
+ setting->if_fmt = plat_data->default_ifmt;
+ }
+ /* Peter's VDAC requires OE to be low active */
+ setting->fbi->var.sync |= FB_SYNC_OE_LOW_ACT;
+
+ INIT_LIST_HEAD(&setting->fbi->modelist);
+ for (i = 0; i < modedb_sz; i++) {
+ struct fb_videomode m;
+ fb_var_to_videomode(&m, &setting->fbi->var);
+ if (fb_mode_is_equal(&m, &modedb[i])) {
+ fb_add_videomode(&modedb[i],
+ &setting->fbi->modelist);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void vdacif_deinit(struct mxc_dispdrv_handle *disp)
+{
+ /*TODO*/
+}
+
+static struct mxc_dispdrv_driver vdacif_drv = {
+ .name = DISPDRV_LCD,
+ .init = vdacif_init,
+ .deinit = vdacif_deinit,
+};
+
+static int vdac_get_of_property(struct platform_device *pdev,
+ struct mxc_vdac_platform_data *plat_data)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int err;
+ u32 ipu_id, disp_id;
+ const char *default_ifmt;
+
+ err = of_property_read_string(np, "default_ifmt", &default_ifmt);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property default_ifmt fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "ipu_id", &ipu_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
+ return err;
+ }
+ err = of_property_read_u32(np, "disp_id", &disp_id);
+ if (err) {
+ dev_dbg(&pdev->dev, "get of property disp_id fail\n");
+ return err;
+ }
+
+ if ( (ipu_id == 0) || (disp_id == 1) ) {
+ dev_err(&pdev->dev, "wrong ipu_id %x or disp_id %x, expected 1, 0\n", ipu_id, disp_id);
+ }
+ plat_data->ipu_id = ipu_id;
+ plat_data->disp_id = disp_id;
+ if (!strncmp(default_ifmt, "RGB565", 6))
+ plat_data->default_ifmt = IPU_PIX_FMT_RGB565;
+ else {
+ dev_err(&pdev->dev, "err default_ifmt!\n");
+ return -ENOENT;
+ }
+
+ return err;
+}
+
+static int mxc_vdacif_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct pinctrl *pinctrl;
+ struct mxc_vdacif_data *vdacif;
+ struct mxc_vdac_platform_data *plat_data;
+
+ dev_dbg(&pdev->dev, "%s enter\n", __func__);
+ vdacif = devm_kzalloc(&pdev->dev, sizeof(struct mxc_vdacif_data),
+ GFP_KERNEL);
+ if (!vdacif)
+ return -ENOMEM;
+ plat_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct mxc_vdac_platform_data),
+ GFP_KERNEL);
+ if (!plat_data)
+ return -ENOMEM;
+ pdev->dev.platform_data = plat_data;
+
+ ret = vdac_get_of_property(pdev, plat_data);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "get vdac of property fail\n");
+ return ret;
+ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "can't get/select pinctrl\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ vdacif->pdev = pdev;
+ vdacif->disp_vdacif = mxc_dispdrv_register(&vdacif_drv);
+ mxc_dispdrv_setdata(vdacif->disp_vdacif, vdacif);
+
+ dev_set_drvdata(&pdev->dev, vdacif);
+ dev_dbg(&pdev->dev, "%s exit\n", __func__);
+
+ return ret;
+}
+
+static int mxc_vdacif_remove(struct platform_device *pdev)
+{
+ struct mxc_vdacif_data *vdacif = dev_get_drvdata(&pdev->dev);
+
+ mxc_dispdrv_puthandle(vdacif->disp_vdacif);
+ mxc_dispdrv_unregister(vdacif->disp_vdacif);
+ kfree(vdacif);
+ return 0;
+}
+
+static const struct of_device_id imx_vdac_dt_ids[] = {
+ { .compatible = "fsl,vdac"},
+ { /* sentinel */ }
+};
+static struct platform_driver mxc_vdacif_driver = {
+ .driver = {
+ .name = "mxc_vdacif",
+ .of_match_table = imx_vdac_dt_ids,
+ },
+ .probe = mxc_vdacif_probe,
+ .remove = mxc_vdacif_remove,
+};
+
+static int __init mxc_vdacif_init(void)
+{
+ return platform_driver_register(&mxc_vdacif_driver);
+}
+
+static void __exit mxc_vdacif_exit(void)
+{
+ platform_driver_unregister(&mxc_vdacif_driver);
+}
+
+module_init(mxc_vdacif_init);
+module_exit(mxc_vdacif_exit);
+
+MODULE_AUTHOR("Toradex AG");
+MODULE_DESCRIPTION("i.MX ipuv3 VDAC extern port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index b826c17702ed..29b851dfafec 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -268,6 +268,7 @@ struct mxsfb_info {
#ifdef CONFIG_FB_MXC_OVERLAY
struct mxsfb_layer overlay;
#endif
+ char *fb_mode_str;
};
#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
@@ -477,7 +478,7 @@ static const struct fb_bitfield def_rgb444[] = {
.length = 0,
}
};
-#endif
+#endif /* CONFIG_FB_MXC_OVERLAY */
static const struct fb_bitfield def_rgb666[] = {
[RED] = {
@@ -685,7 +686,6 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
"dispdrv:%s\n", host->dispdrv->drv->name);
return;
}
- host->sync = fb_info->var.sync;
}
if (host->reg_lcd) {
@@ -1302,6 +1302,41 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
return 0;
}
+/*
+ * Parse user specified options (`video=')
+ * e.g.:
+ * video=mxsfb:800x480M-16@60,pixclockpol=1,outputen=1
+ */
+static int mxsfb_option_setup(struct mxsfb_info *host, struct fb_info *fb_info)
+{
+ char *options, *opt;
+ struct platform_device *pdev = host->pdev;
+
+ if (fb_get_options(DRIVER_NAME, &options)) {
+ dev_err(&pdev->dev, "Can't get fb option for %s!\n", DRIVER_NAME);
+ return -ENODEV;
+ }
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt) {
+ continue;
+ } else if (!strncmp(opt, "pixclockpol=", 12)) {
+ if(simple_strtoul(opt + 12, NULL, 0))
+ host->sync |= FB_SYNC_CLK_LAT_FALL;
+ } else if (!strncmp(opt, "outputen=", 9)) {
+ if(simple_strtoul(opt + 9, NULL, 0))
+ host->sync |= FB_SYNC_OE_LOW_ACT;
+ } else {
+ host->fb_mode_str = opt;
+ }
+ }
+
+ return 0;
+}
+
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
{
struct fb_info *fb_info = host->fb_info;
@@ -1309,12 +1344,14 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
struct device *dev = &host->pdev->dev;
struct device_node *np = host->pdev->dev.of_node;
struct device_node *display_np;
- struct device_node *timings_np;
struct display_timings *timings = NULL;
const char *disp_dev, *disp_videomode;
+ struct videomode vm;
+ struct fb_videomode fb_vm;
+ struct fb_videomode native_mode;
u32 width;
int i;
- int ret = 0;
+ int ret = 0, retval = 0;
host->id = of_alias_get_id(np, "lcdif");
@@ -1377,34 +1414,67 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
goto put_display_node;
}
- timings_np = of_find_node_by_name(display_np,
- "display-timings");
- if (!timings_np) {
- dev_err(dev, "failed to find display-timings node\n");
- ret = -ENOENT;
- goto put_display_node;
- }
-
- for (i = 0; i < of_get_child_count(timings_np); i++) {
- struct videomode vm;
- struct fb_videomode fb_vm;
+ INIT_LIST_HEAD(&fb_info->modelist);
+ for (i = 0; i < timings->num_timings; i++) {
ret = videomode_from_timings(timings, &vm, i);
if (ret < 0)
- goto put_timings_node;
+ goto put_display_node;
+
ret = fb_videomode_from_videomode(&vm, &fb_vm);
if (ret < 0)
- goto put_timings_node;
+ goto put_display_node;
if (!(vm.flags & DISPLAY_FLAGS_DE_HIGH))
fb_vm.sync |= FB_SYNC_OE_LOW_ACT;
- if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+
+ /*
+ * The PIXDATA flags of the display_flags enum are controller
+ * centric, e.g. NEGEDGE means drive data on negative edge.
+ * However, the drivers flag is display centric: Sample the
+ * data on negative (falling) edge. Therefore, check for the
+ * POSEDGE flag:
+ * drive on positive edge => sample on negative edge
+ */
+ if (vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
fb_vm.sync |= FB_SYNC_CLK_LAT_FALL;
+
+ if (i == timings->native_mode) {
+ native_mode = fb_vm;
+ fb_videomode_to_var(&fb_info->var, &fb_vm);
+ }
+
fb_add_videomode(&fb_vm, &fb_info->modelist);
}
-put_timings_node:
- of_node_put(timings_np);
+ retval = fb_find_mode(&fb_info->var, fb_info, host->fb_mode_str, &fb_vm,
+ timings->num_timings, &native_mode,
+ fb_info->var.bits_per_pixel);
+ if (retval != 1)
+ /* save the sync value getting from dtb */
+ host->sync = fb_info->var.sync;
+
+ switch (retval) {
+ case 0:
+ dev_err(dev, "fb_find_mode can't find a "
+ "suitable timing\n");
+ break;
+ case 1:
+ dev_info(dev, "Using timings from kernel parameters\n");
+ break;
+ case 2:
+ dev_info(dev, "Using timings from kernel parameters "
+ "and ignoring refresh rate\n");
+ break;
+ case 3:
+ dev_info(dev, "Using timings from devicetree\n");
+ break;
+ case 4:
+ dev_warn(dev, "Falling back to any valid timing\n");
+ default:
+ break;
+ }
+
put_display_node:
if (timings)
kfree(timings);
@@ -1417,7 +1487,6 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
int ret;
struct fb_info *fb_info = host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
- struct fb_modelist *modelist;
fb_info->fbops = &mxsfb_ops;
fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
@@ -1427,6 +1496,10 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
fb_info->fix.accel = FB_ACCEL_NONE;
+ ret = mxsfb_option_setup(host, fb_info);
+ if (ret)
+ return ret;
+
ret = mxsfb_init_fbinfo_dt(host);
if (ret)
return ret;
@@ -1436,15 +1509,6 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
else
sprintf(fb_info->fix.id, "mxs-lcdif%d", host->id);
- if (!list_empty(&fb_info->modelist)) {
- /* first video mode in the modelist as default video mode */
- modelist = list_first_entry(&fb_info->modelist,
- struct fb_modelist, list);
- fb_videomode_to_var(var, &modelist->mode);
- }
- /* save the sync value getting from dtb */
- host->sync = fb_info->var.sync;
-
var->nonstd = 0;
var->activate = FB_ACTIVATE_NOW;
var->accel_flags = 0;
@@ -2177,11 +2241,14 @@ static void mxsfb_overlay_suspend(struct mxsfb_info *fbi)
clk_disable_pix(fbi);
}
}
-#endif
+#endif /* CONFIG_PM_SLEEP */
-#else
+#else /* CONFIG_FB_MXC_OVERLAY */
static void mxsfb_overlay_init(struct mxsfb_info *fbi) {}
static void mxsfb_overlay_exit(struct mxsfb_info *fbi) {}
+#endif /* CONFIG_FB_MXC_OVERLAY */
+
+#if !(defined(CONFIG_FB_MXC_OVERLAY) && defined(CONFIG_PM_SLEEP))
static void mxsfb_overlay_resume(struct mxsfb_info *fbi) {}
static void mxsfb_overlay_suspend(struct mxsfb_info *fbi) {}
#endif
@@ -2291,8 +2358,6 @@ static int mxsfb_probe(struct platform_device *pdev)
goto fb_release;
}
- INIT_LIST_HEAD(&fb_info->modelist);
-
pm_runtime_enable(&host->pdev->dev);
ret = mxsfb_init_fbinfo(host);
@@ -2438,7 +2503,7 @@ static int mxsfb_runtime_resume(struct device *dev)
return 0;
}
-#endif
+#endif /* CONFIG_PM */
#ifdef CONFIG_PM_SLEEP
static int mxsfb_suspend(struct device *pdev)
@@ -2455,6 +2520,7 @@ static int mxsfb_suspend(struct device *pdev)
host->restore_blank = saved_blank;
console_unlock();
+ pm_runtime_force_suspend(&host->pdev->dev);
pinctrl_pm_select_sleep_state(pdev);
return 0;
@@ -2466,6 +2532,7 @@ static int mxsfb_resume(struct device *pdev)
struct fb_info *fb_info = host->fb_info;
pinctrl_pm_select_default_state(pdev);
+ pm_runtime_force_resume(&host->pdev->dev);
console_lock();
mxsfb_overlay_resume(host);
@@ -2475,7 +2542,7 @@ static int mxsfb_resume(struct device *pdev)
return 0;
}
-#endif
+#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops mxsfb_pm_ops = {
SET_RUNTIME_PM_OPS(mxsfb_runtime_suspend, mxsfb_runtime_resume, NULL)
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 6d6f8c08792d..d8e3a0c7c653 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -68,4 +68,8 @@ config LOGO_SUPERH_CLUT224
depends on SUPERH
default y
+config LOGO_CUSTOM_CLUT224
+ bool "Custom 224-color Linux logo"
+ default n
+
endif # LOGO
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index 16f60c1e1766..4aba1b9e3106 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o
obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o
+obj-$(CONFIG_LOGO_CUSTOM_CLUT224) += logo_custom_clut224.o
+
# How to generate logo's
pnmtologo := scripts/pnmtologo
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 141f15a9a459..ec3f00502a96 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -100,6 +100,10 @@ const struct linux_logo * __ref fb_find_logo(int depth)
/* SuperH Linux logo */
logo = &logo_superh_clut224;
#endif
+#ifdef CONFIG_LOGO_CUSTOM_CLUT224
+ /* Custom Linux logo */
+ logo = &logo_custom_clut224;
+#endif
}
return logo;
}
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c
index 46d534e3eab0..5408fa3db68f 100644
--- a/drivers/watchdog/imx_sc_wdt.c
+++ b/drivers/watchdog/imx_sc_wdt.c
@@ -66,7 +66,12 @@ static int imx_sc_wdt_start(struct watchdog_device *wdog)
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT,
SC_TIMER_WDOG_ACTION_PARTITION,
0, 0, 0, 0, 0, &res);
- return res.a0 ? -EACCES : 0;
+ if (res.a0)
+ return -EACCES;
+
+ dev_dbg(wdog->parent, "Watchdog started\n");
+
+ return 0;
}
static int imx_sc_wdt_stop(struct watchdog_device *wdog)
@@ -76,6 +81,8 @@ static int imx_sc_wdt_stop(struct watchdog_device *wdog)
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_STOP_WDOG,
0, 0, 0, 0, 0, 0, &res);
+ dev_dbg(wdog->parent, "Watchdog stopped\n");
+
return res.a0 ? -EACCES : 0;
}
@@ -88,6 +95,8 @@ static int imx_sc_wdt_set_timeout(struct watchdog_device *wdog,
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_TIMEOUT_WDOG,
timeout * 1000, 0, 0, 0, 0, 0, &res);
+ dev_dbg(wdog->parent, "Set timeout to %d seconds\n", timeout);
+
return res.a0 ? -EACCES : 0;
}
@@ -109,6 +118,8 @@ static int imx_sc_wdt_set_pretimeout(struct watchdog_device *wdog,
wdog->pretimeout = pretimeout;
+ dev_dbg(wdog->parent, "Set pretimeout to %d seconds\n", pretimeout);
+
return 0;
}
diff --git a/include/drm/bridge/cdns-mhdp.h b/include/drm/bridge/cdns-mhdp.h
index 86314543fbca..5176ef0c1955 100755
--- a/include/drm/bridge/cdns-mhdp.h
+++ b/include/drm/bridge/cdns-mhdp.h
@@ -723,6 +723,7 @@ struct cdns_mhdp_device {
hdmi_codec_plugged_cb plugged_cb;
struct device *codec_dev;
enum drm_connector_status last_connector_result;
+ struct i2c_adapter *ddc; /* optional regular DDC I2C bus */
};
u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset);
diff --git a/include/linux/input/fusion_F0710A.h b/include/linux/input/fusion_F0710A.h
new file mode 100644
index 000000000000..7d152cbdd06e
--- /dev/null
+++ b/include/linux/input/fusion_F0710A.h
@@ -0,0 +1,20 @@
+/* linux/input/fusion_F0710A.h
+ *
+ * Platform data for Fusion F0710A driver
+ *
+ * Copyright (c) 2013 Toradex AG (stefan.agner@toradex.ch)
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+
+#ifndef __LINUX_I2C_FUSION_F0710A_H
+#define __LINUX_I2C_FUSION_F0710A_H
+
+/* Board specific touch screen initial values */
+struct fusion_f0710a_init_data {
+ int (*pinmux_fusion_pins)(void);
+ int gpio_int;
+ int gpio_reset;
+};
+
+#endif /* __LINUX_I2C_FUSION_F0710A_H */
diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h
index d4d5b93efe84..57814768be44 100644
--- a/include/linux/linux_logo.h
+++ b/include/linux/linux_logo.h
@@ -45,6 +45,7 @@ extern const struct linux_logo logo_superh_mono;
extern const struct linux_logo logo_superh_vga16;
extern const struct linux_logo logo_superh_clut224;
extern const struct linux_logo logo_spe_clut224;
+extern const struct linux_logo logo_custom_clut224;
extern const struct linux_logo *fb_find_logo(int depth);
#ifdef CONFIG_FB_LOGO_EXTRA
diff --git a/include/linux/mfd/pca9450.h b/include/linux/mfd/pca9450.h
index 80e45c5e0472..ecda7fa18b61 100644
--- a/include/linux/mfd/pca9450.h
+++ b/include/linux/mfd/pca9450.h
@@ -92,6 +92,9 @@ enum {
PCA9450_MAX_REGISTER = 0x2F,
};
+/* PCA9450_BUCK123_DVS */
+#define BUCK123_PRESET_EN 0x80
+
/* PCA9450 BUCK ENMODE bits */
#define BUCK_ENMODE_OFF 0x00
#define BUCK_ENMODE_ONREQ 0x01
@@ -230,6 +233,7 @@ enum {
struct pca9450_board {
struct regulator_init_data *init_data[PCA9450_REGULATOR_CNT];
int gpio_intr;
+ int i2c_lt_en;
int irq_base;
};
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 67bf6cbe75ab..a38031890752 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -342,6 +342,7 @@ struct phy_c45_device_ids {
* suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus.
* sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal.
* loopback_enabled: Set true if this phy has been loopbacked successfully.
+ * mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY
* state: state of the PHY for management purposes
* dev_flags: Device-specific flags used by the PHY driver.
* irq: IRQ number of the PHY's interrupt (-1 if none)
@@ -379,6 +380,7 @@ struct phy_device {
unsigned suspended_by_mdio_bus:1;
unsigned sysfs_links:1;
unsigned loopback_enabled:1;
+ unsigned mac_managed_pm:1;
unsigned autoneg:1;
/* The most recently read link state */
diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h
index a48ff69acddd..98df234834bd 100644
--- a/include/linux/pinctrl/devinfo.h
+++ b/include/linux/pinctrl/devinfo.h
@@ -14,11 +14,11 @@
#ifndef PINCTRL_DEVINFO_H
#define PINCTRL_DEVINFO_H
-#ifdef CONFIG_PINCTRL
-
/* The device core acts as a consumer toward pinctrl */
#include <linux/pinctrl/consumer.h>
+#ifdef CONFIG_PINCTRL
+
/**
* struct dev_pin_info - pin state container for devices
* @p: pinctrl handle for the containing device
diff --git a/include/linux/platform_data/usb3503.h b/include/linux/platform_data/usb3503.h
index e049d51c1353..435e9edb1bc4 100644
--- a/include/linux/platform_data/usb3503.h
+++ b/include/linux/platform_data/usb3503.h
@@ -16,7 +16,9 @@ enum usb3503_mode {
struct usb3503_platform_data {
enum usb3503_mode initial_mode;
+ u8 port_nrd;
u8 port_off_mask;
+ int gpio_bypass;
int gpio_intn;
int gpio_connect;
int gpio_reset;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index eb28c802570d..eb2b885de9b5 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -374,6 +374,12 @@ const struct dev_pm_ops name = { \
SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
}
+#ifdef CONFIG_PM
+#define pm_ptr(_ptr) (_ptr)
+#else
+#define pm_ptr(_ptr) NULL
+#endif
+
/*
* PM_EVENT_ messages
*
diff --git a/include/linux/sync.h b/include/linux/sync.h
new file mode 100644
index 000000000000..4f1993871467
--- /dev/null
+++ b/include/linux/sync.h
@@ -0,0 +1,390 @@
+/*
+ * include/linux/sync.h
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_SYNC_H
+#define _LINUX_SYNC_H
+
+#include <linux/types.h>
+#ifdef __KERNEL__
+
+#include <linux/ktime.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+struct sync_timeline;
+struct sync_pt;
+struct sync_fence;
+
+/**
+ * struct sync_timeline_ops - sync object implementation ops
+ * @driver_name: name of the implentation
+ * @dup: duplicate a sync_pt
+ * @has_signaled: returns:
+ * 1 if pt has signaled
+ * 0 if pt has not signaled
+ * <0 on error
+ * @compare: returns:
+ * 1 if b will signal before a
+ * 0 if a and b will signal at the same time
+ * -1 if a will signabl before b
+ * @free_pt: called before sync_pt is freed
+ * @release_obj: called before sync_timeline is freed
+ * @print_obj: print aditional debug information about sync_timeline.
+ * should not print a newline
+ * @print_pt: print aditional debug information about sync_pt.
+ * should not print a newline
+ * @fill_driver_data: write implmentation specific driver data to data.
+ * should return an error if there is not enough room
+ * as specified by size. This information is returned
+ * to userspace by SYNC_IOC_FENCE_INFO.
+ */
+struct sync_timeline_ops {
+ const char *driver_name;
+
+ /* required */
+ struct sync_pt *(*dup)(struct sync_pt *pt);
+
+ /* required */
+ int (*has_signaled)(struct sync_pt *pt);
+
+ /* required */
+ int (*compare)(struct sync_pt *a, struct sync_pt *b);
+
+ /* optional */
+ void (*free_pt)(struct sync_pt *sync_pt);
+
+ /* optional */
+ void (*release_obj)(struct sync_timeline *sync_timeline);
+
+ /* optional */
+ void (*print_obj)(struct seq_file *s,
+ struct sync_timeline *sync_timeline);
+
+ /* optional */
+ void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
+
+ /* optional */
+ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
+};
+
+/**
+ * struct sync_timeline - sync object
+ * @ops: ops that define the implementaiton of the sync_timeline
+ * @name: name of the sync_timeline. Useful for debugging
+ * @destoryed: set when sync_timeline is destroyed
+ * @child_list_head: list of children sync_pts for this sync_timeline
+ * @child_list_lock: lock protecting @child_list_head, destroyed, and
+ * sync_pt.status
+ * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @sync_timeline_list: membership in global sync_timeline_list
+ */
+struct sync_timeline {
+ const struct sync_timeline_ops *ops;
+ char name[32];
+
+ /* protected by child_list_lock */
+ bool destroyed;
+
+ struct list_head child_list_head;
+ spinlock_t child_list_lock;
+
+ struct list_head active_list_head;
+ spinlock_t active_list_lock;
+
+ struct list_head sync_timeline_list;
+};
+
+/**
+ * struct sync_pt - sync point
+ * @parent: sync_timeline to which this sync_pt belongs
+ * @child_list: membership in sync_timeline.child_list_head
+ * @active_list: membership in sync_timeline.active_list_head
+ * @fence: sync_fence to which the sync_pt belongs
+ * @pt_list: membership in sync_fence.pt_list_head
+ * @status: 1: signaled, 0:active, <0: error
+ * @timestamp: time which sync_pt status transitioned from active to
+ * singaled or error.
+ */
+struct sync_pt {
+ struct sync_timeline *parent;
+ struct list_head child_list;
+
+ struct list_head active_list;
+
+ struct sync_fence *fence;
+ struct list_head pt_list;
+
+ /* protected by parent->active_list_lock */
+ int status;
+
+ ktime_t timestamp;
+};
+
+/**
+ * struct sync_fence - sync fence
+ * @file: file representing this fence
+ * @name: name of sync_fence. Useful for debugging
+ * @pt_list_head: list of sync_pts in ths fence. immutable once fence
+ * is created
+ * @waiter_list_head: list of asynchronous waiters on this fence
+ * @waiter_list_lock: lock protecting @waiter_list_head and @status
+ * @status: 1: signaled, 0:active, <0: error
+ *
+ * @wq: wait queue for fence signaling
+ * @sync_fence_list: membership in global fence list
+ */
+struct sync_fence {
+ struct file *file;
+ char name[32];
+
+ /* this list is immutable once the fence is created */
+ struct list_head pt_list_head;
+
+ struct list_head waiter_list_head;
+ spinlock_t waiter_list_lock; /* also protects status */
+ int status;
+
+ wait_queue_head_t wq;
+
+ struct list_head sync_fence_list;
+};
+
+/**
+ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
+ * @waiter_list: membership in sync_fence.waiter_list_head
+ * @callback: function pointer to call when fence signals
+ * @callback_data: pointer to pass to @callback
+ */
+struct sync_fence_waiter {
+ struct list_head waiter_list;
+
+ void (*callback)(struct sync_fence *fence, void *data);
+ void *callback_data;
+};
+
+/*
+ * API for sync_timeline implementers
+ */
+
+/**
+ * sync_timeline_create() - creates a sync object
+ * @ops: specifies the implemention ops for the object
+ * @size: size to allocate for this obj
+ * @name: sync_timeline name
+ *
+ * Creates a new sync_timeline which will use the implemetation specified by
+ * @ops. @size bytes will be allocated allowing for implemntation specific
+ * data to be kept after the generic sync_timeline stuct.
+ */
+struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
+ int size, const char *name);
+
+/**
+ * sync_timeline_destory() - destorys a sync object
+ * @obj: sync_timeline to destroy
+ *
+ * A sync implemntation should call this when the @obj is going away
+ * (i.e. module unload.) @obj won't actually be freed until all its childern
+ * sync_pts are freed.
+ */
+void sync_timeline_destroy(struct sync_timeline *obj);
+
+/**
+ * sync_timeline_signal() - signal a status change on a sync_timeline
+ * @obj: sync_timeline to signal
+ *
+ * A sync implemntation should call this any time one of it's sync_pts
+ * has signaled or has an error condition.
+ */
+void sync_timeline_signal(struct sync_timeline *obj);
+
+/**
+ * sync_pt_create() - creates a sync pt
+ * @parent: sync_pt's parent sync_timeline
+ * @size: size to allocate for this pt
+ *
+ * Creates a new sync_pt as a chiled of @parent. @size bytes will be
+ * allocated allowing for implemntation specific data to be kept after
+ * the generic sync_timeline struct.
+ */
+struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
+
+/**
+ * sync_pt_free() - frees a sync pt
+ * @pt: sync_pt to free
+ *
+ * This should only be called on sync_pts which have been created but
+ * not added to a fence.
+ */
+void sync_pt_free(struct sync_pt *pt);
+
+/**
+ * sync_fence_create() - creates a sync fence
+ * @name: name of fence to create
+ * @pt: sync_pt to add to the fence
+ *
+ * Creates a fence containg @pt. Once this is called, the fence takes
+ * ownership of @pt.
+ */
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
+
+/*
+ * API for sync_fence consumers
+ */
+
+/**
+ * sync_fence_merge() - merge two fences
+ * @name: name of new fence
+ * @a: fence a
+ * @b: fence b
+ *
+ * Creates a new fence which contains copies of all the sync_pts in both
+ * @a and @b. @a and @b remain valid, independent fences.
+ */
+struct sync_fence *sync_fence_merge(const char *name,
+ struct sync_fence *a, struct sync_fence *b);
+
+/**
+ * sync_fence_fdget() - get a fence from an fd
+ * @fd: fd referencing a fence
+ *
+ * Ensures @fd references a valid fence, increments the refcount of the backing
+ * file, and returns the fence.
+ */
+struct sync_fence *sync_fence_fdget(int fd);
+
+/**
+ * sync_fence_put() - puts a refernnce of a sync fence
+ * @fence: fence to put
+ *
+ * Puts a reference on @fence. If this is the last reference, the fence and
+ * all it's sync_pts will be freed
+ */
+void sync_fence_put(struct sync_fence *fence);
+
+/**
+ * sync_fence_install() - installs a fence into a file descriptor
+ * @fence: fence to instal
+ * @fd: file descriptor in which to install the fence
+ *
+ * Installs @fence into @fd. @fd's should be acquired through get_unused_fd().
+ */
+void sync_fence_install(struct sync_fence *fence, int fd);
+
+/**
+ * sync_fence_wait_async() - registers and async wait on the fence
+ * @fence: fence to wait on
+ * @callback: callback
+ * @callback_data data to pass to the callback
+ *
+ * Returns 1 if @fence has already signaled.
+ *
+ * Registers a callback to be called when @fence signals or has an error
+ */
+int sync_fence_wait_async(struct sync_fence *fence,
+ void (*callback)(struct sync_fence *, void *data),
+ void *callback_data);
+
+/**
+ * sync_fence_wait() - wait on fence
+ * @fence: fence to wait on
+ * @tiemout: timeout in ms
+ *
+ * Wait for @fence to be signaled or have an error. Waits indefintly
+ * if @timeout = 0
+ */
+int sync_fence_wait(struct sync_fence *fence, long timeout);
+
+#endif /* __KERNEL__ */
+
+/**
+ * struct sync_merge_data - data passed to merge ioctl
+ * @fd2: file descriptor of second fence
+ * @name: name of new fence
+ * @fence: returns the fd of the new fence to userspace
+ */
+struct sync_merge_data {
+ __s32 fd2; /* fd of second fence */
+ char name[32]; /* name of new fence */
+ __s32 fence; /* fd on newly created fence */
+};
+
+/**
+ * struct sync_pt_info - detailed sync_pt information
+ * @len: length of sync_pt_info including any driver_data
+ * @obj_name: name of parent sync_timeline
+ * @driver_name: name of driver implmenting the parent
+ * @status: status of the sync_pt 0:active 1:signaled <0:error
+ * @timestamp_ns: timestamp of status change in nanoseconds
+ * @driver_data: any driver dependant data
+ */
+struct sync_pt_info {
+ __u32 len;
+ char obj_name[32];
+ char driver_name[32];
+ __s32 status;
+ __u64 timestamp_ns;
+
+ __u8 driver_data[0];
+};
+
+/**
+ * struct sync_fence_info_data - data returned from fence info ioctl
+ * @len: ioctl caller writes the size of the buffer its passing in.
+ * ioctl returns length of sync_fence_data reutnred to userspace
+ * including pt_info.
+ * @name: name of fence
+ * @status: status of fence. 1: signaled 0:active <0:error
+ * @pt_info: a sync_pt_info struct for every sync_pt in the fence
+ */
+struct sync_fence_info_data {
+ __u32 len;
+ char name[32];
+ __s32 status;
+
+ __u8 pt_info[0];
+};
+
+#define SYNC_IOC_MAGIC '>'
+
+/**
+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal
+ *
+ * pass timeout in milliseconds.
+ */
+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __u32)
+
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
+ * new fence's fd in sync_merge_data.fence
+ */
+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
+
+/**
+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len. On return, len is
+ * updated to reflect the total size of the sync_fence_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To itterate over the sync_pt_infos, use the sync_pt_info.len field.
+ */
+#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\
+ struct sync_fence_info_data)
+
+#endif /* _LINUX_SYNC_H */
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index b4c8416c3d1f..284d4d1695c5 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -185,6 +185,9 @@ enum {
/* module saa7191: just ident 7191 */
V4L2_IDENT_SAA7191 = 7191,
+ /* module adv7280: just ident 7280 */
+ V4L2_IDENT_ADV7280 = 7280,
+
/* module ths7303: just ident 7303 */
V4L2_IDENT_THS7303 = 7303,
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 187f7822047a..2947db543ad9 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -198,6 +198,15 @@ struct v4l2_subdev_core_ops {
int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
+#ifdef CONFIG_VIDEO_ECAM
+ int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
+ int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+ int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+ int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
+ int (*g_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
+ int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
+ int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
+#endif
long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
#ifdef CONFIG_COMPAT
diff --git a/include/video/mxc_hdmi.h b/include/video/mxc_hdmi.h
index 79eb3024f65c..bb0d33a2d460 100644
--- a/include/video/mxc_hdmi.h
+++ b/include/video/mxc_hdmi.h
@@ -573,6 +573,10 @@ enum {
HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
+/* IH and IH_MUTE convenience macro RX_SENSE | HPD*/
+ HDMI_DVI_IH_STAT = 0x3D,
+
+
/* IH_AHBDMAAUD_STAT0 field values */
HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
@@ -871,6 +875,9 @@ enum {
HDMI_PHY_HPD = 0x02,
HDMI_PHY_TX_PHY_LOCK = 0x01,
+/* HDMI STAT convenience RX_SENSE | HPD */
+ HDMI_DVI_STAT = 0xF2,
+
/* PHY_I2CM_SLAVE_ADDR field values */
HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ee57fa20bac3..f07a2b11c3c9 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -726,20 +726,17 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
hci_dev_lock(hdev);
conn = hci_lookup_le_connect(hdev);
+ if (!conn)
+ goto done;
if (!status) {
hci_connect_le_scan_cleanup(conn);
- goto done;
+ } else {
+ BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
+ status);
+ hci_le_conn_failed(conn, status);
}
- bt_dev_err(hdev, "request failed to create LE connection: "
- "status 0x%2.2x", status);
-
- if (!conn)
- goto done;
-
- hci_le_conn_failed(conn, status);
-
done:
hci_dev_unlock(hdev);
}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 211007c091d5..19959fb5df4e 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config WIRELESS_EXT
- bool
+ bool "WIRELESS_EXT - wireless core extensions"
config WEXT_CORE
def_bool y
@@ -15,7 +15,7 @@ config WEXT_SPY
bool
config WEXT_PRIV
- bool
+ bool "WEXT_PRIV - Wireless Extensions priv API"
config CFG80211
tristate "cfg80211 - wireless configuration API"
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index a358af93cd7f..2a45d987be90 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -51,7 +51,7 @@ my %ignore_type = ();
my @ignore = ();
my $help = 0;
my $configuration_file = ".checkpatch.conf";
-my $max_line_length = 80;
+my $max_line_length = 100;
my $ignore_perl_version = 0;
my $minimum_perl_version = 5.10.0;
my $min_conf_desc_length = 4;
@@ -64,6 +64,7 @@ my $color = "auto";
my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
# git output parsing needs US English output, so first set backtick child process LANGUAGE
my $git_command ='export LANGUAGE=en_US.UTF-8; git';
+my $tabsize = 8;
sub help {
my ($exitcode) = @_;
@@ -96,8 +97,11 @@ Options:
--types TYPE(,TYPE2...) show only these comma separated message types
--ignore TYPE(,TYPE2...) ignore various comma separated message types
--show-types show the specific message type in the output
- --max-line-length=n set the maximum line length, if exceeded, warn
+ --max-line-length=n set the maximum line length, (default $max_line_length)
+ if exceeded, warn on patches
+ requires --strict for use with --file
--min-conf-desc-length=n set the min description length, if shorter, warn
+ --tab-size=n set the number of spaces for tab (default $tabsize)
--root=PATH PATH to the kernel tree root
--no-summary suppress the per-file summary
--mailback only produce a report in case of warnings/errors
@@ -215,6 +219,7 @@ GetOptions(
'list-types!' => \$list_types,
'max-line-length=i' => \$max_line_length,
'min-conf-desc-length=i' => \$min_conf_desc_length,
+ 'tab-size=i' => \$tabsize,
'root=s' => \$root,
'summary!' => \$summary,
'mailback!' => \$mailback,
@@ -267,6 +272,9 @@ if ($color =~ /^[01]$/) {
die "Invalid color mode: $color\n";
}
+# skip TAB size 1 to avoid additional checks on $tabsize - 1
+die "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
+
sub hash_save_array_words {
my ($hashRef, $arrayRef) = @_;
@@ -1213,7 +1221,7 @@ sub expand_tabs {
if ($c eq "\t") {
$res .= ' ';
$n++;
- for (; ($n % 8) != 0; $n++) {
+ for (; ($n % $tabsize) != 0; $n++) {
$res .= ' ';
}
next;
@@ -2226,7 +2234,7 @@ sub string_find_replace {
sub tabify {
my ($leading) = @_;
- my $source_indent = 8;
+ my $source_indent = $tabsize;
my $max_spaces_before_tab = $source_indent - 1;
my $spaces_to_tab = " " x $source_indent;
@@ -3171,8 +3179,10 @@ sub process {
if ($msg_type ne "" &&
(show_type("LONG_LINE") || show_type($msg_type))) {
- WARN($msg_type,
- "line over $max_line_length characters\n" . $herecurr);
+ my $msg_level = \&WARN;
+ $msg_level = \&CHK if ($file);
+ &{$msg_level}($msg_type,
+ "line length of $length exceeds $max_line_length columns\n" . $herecurr);
}
}
@@ -3186,7 +3196,7 @@ sub process {
next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
# at the beginning of a line any tabs must come first and anything
-# more than 8 must use tabs.
+# more than $tabsize must use tabs.
if ($rawline =~ /^\+\s* \t\s*\S/ ||
$rawline =~ /^\+\s* \s*/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@@ -3205,7 +3215,7 @@ sub process {
"please, no space before tabs\n" . $herevet) &&
$fix) {
while ($fixed[$fixlinenr] =~
- s/(^\+.*) {8,8}\t/$1\t\t/) {}
+ s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
while ($fixed[$fixlinenr] =~
s/(^\+.*) +\t/$1\t/) {}
}
@@ -3227,11 +3237,11 @@ sub process {
if ($perl_version_ok &&
$sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
my $indent = length($1);
- if ($indent % 8) {
+ if ($indent % $tabsize) {
if (WARN("TABSTOP",
"Statements should start on a tabstop\n" . $herecurr) &&
$fix) {
- $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
+ $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
}
}
}
@@ -3249,8 +3259,8 @@ sub process {
my $newindent = $2;
my $goodtabindent = $oldindent .
- "\t" x ($pos / 8) .
- " " x ($pos % 8);
+ "\t" x ($pos / $tabsize) .
+ " " x ($pos % $tabsize);
my $goodspaceindent = $oldindent . " " x $pos;
if ($newindent ne $goodtabindent &&
@@ -3721,11 +3731,11 @@ sub process {
#print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
if ($check && $s ne '' &&
- (($sindent % 8) != 0 ||
+ (($sindent % $tabsize) != 0 ||
($sindent < $indent) ||
($sindent == $indent &&
($s !~ /^\s*(?:\}|\{|else\b)/)) ||
- ($sindent > $indent + 8))) {
+ ($sindent > $indent + $tabsize))) {
WARN("SUSPECT_CODE_INDENT",
"suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
}
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 64c5d64cf4eb..e83c333a81cb 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -722,7 +722,7 @@ config SND_SOC_HDAC_HDA
select SND_HDA
config SND_SOC_ICS43432
- tristate
+ tristate "InvenSense ICS43432 I2S microphone codec"
config SND_SOC_INNO_RK3036
tristate "Inno codec driver for RK3036 SoC"
diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
index 78db3bd0b3bc..a57e7ea0c4fe 100644
--- a/sound/soc/codecs/nau8822.c
+++ b/sound/soc/codecs/nau8822.c
@@ -351,6 +351,8 @@ static const struct snd_kcontrol_new nau8822_snd_controls[] = {
NAU8822_REG_LHP_VOLUME,
NAU8822_REG_RHP_VOLUME, 0, 63, 0, spk_tlv),
+ SOC_SINGLE("Speaker RInversion Switch",
+ NAU8822_REG_RIGHT_SPEAKER_CONTROL, 4, 1, 0),
SOC_DOUBLE_R("Speaker ZC Switch",
NAU8822_REG_LSPKOUT_VOLUME,
NAU8822_REG_RSPKOUT_VOLUME, 7, 1, 0),
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 8a1e485982d8..130efc243b38 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1514,8 +1514,34 @@ err:
return ret;
}
+static int sgtl5000_suspend(struct snd_soc_component *component)
+{
+ struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
+
+ clk_disable_unprepare(sgtl5000->mclk);
+
+ return 0;
+}
+
+static int sgtl5000_resume(struct snd_soc_component *component)
+{
+ int ret;
+ struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
+
+ ret = clk_prepare_enable(sgtl5000->mclk);
+ if (ret)
+ dev_err(component->dev, "Error enabling clock %d\n", ret);
+
+ /* Need 8 clocks before I2C accesses */
+ udelay(1);
+
+ return ret;
+}
+
static const struct snd_soc_component_driver sgtl5000_driver = {
.probe = sgtl5000_probe,
+ .suspend = sgtl5000_suspend,
+ .resume = sgtl5000_resume,
.set_bias_level = sgtl5000_set_bias_level,
.controls = sgtl5000_snd_controls,
.num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 9e8c564f6e9c..b174a9381c0c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1417,6 +1417,13 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
struct snd_soc_component *component = dai->component;
struct wm8904_priv *priv = snd_soc_component_get_drvdata(component);
+ /*
+ * If using sound-simple-card this is called with clk_id fixed to 0.
+ * Assume we want WM8904_CLK_MCLK for now in that case.
+ */
+ if (clk_id == 0)
+ clk_id = WM8904_CLK_MCLK;
+
switch (clk_id) {
case WM8904_CLK_MCLK:
priv->sysclk_src = clk_id;
diff --git a/sound/soc/fsl/fsl_dsp.c b/sound/soc/fsl/fsl_dsp.c
index e64f9bb8af71..1bb72b10e41a 100644
--- a/sound/soc/fsl/fsl_dsp.c
+++ b/sound/soc/fsl/fsl_dsp.c
@@ -70,6 +70,63 @@
#include "fsl_dsp_pool.h"
#include "fsl_dsp_xaf_api.h"
+#define DSP_DISABLE_FUSE 0x8
+#define DSP_DISABLE_MASK 0x1
+
+struct dsp_sc_msg_misc {
+ struct imx_sc_rpc_msg hdr;
+ u32 word;
+} __packed;
+
+static int dsp_sc_get_fuse(struct imx_sc_ipc *ipc, u32 word, u32 *fuse)
+{
+ struct dsp_sc_msg_misc msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_MISC;
+ hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+ hdr->size = 2;
+
+ msg.word = word;
+
+ ret = imx_scu_call_rpc(ipc, &msg, true);
+ if (ret)
+ return ret;
+
+ *fuse = msg.word;
+
+ return ret;
+}
+
+static int check_dsp_is_available(void)
+{
+ uint32_t fuse = 0xffff;
+ int ret = 0;
+ struct imx_sc_ipc *ipcHandle;;
+
+ ret = imx_scu_get_handle(&ipcHandle);
+ if (ret) {
+ /* We're not running on a iMX8 or iMX8X, so there is no DSP */
+ return -EINVAL;
+ }
+
+ ret = dsp_sc_get_fuse(ipcHandle, DSP_DISABLE_FUSE, &fuse);
+ if (ret) {
+ pr_err("sc_misc_otp_fuse_read fail! %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("DSP disable fuse[%i] = 0x%x\n", DSP_DISABLE_FUSE, fuse);
+ if (fuse & DSP_DISABLE_MASK) {
+ pr_info("%s: HiFi4 DSP not available on this silicon\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* ...allocate new client */
struct xf_client *xf_client_alloc(struct fsl_dsp *dsp_priv)
{
@@ -1653,7 +1710,22 @@ static struct platform_driver fsl_dsp_driver = {
.pm = &fsl_dsp_pm,
},
};
-module_platform_driver(fsl_dsp_driver);
+
+static int __init fsl_dsp_driver_init(void)
+{
+ /* do not install the driver if no DSP is found */
+ if (check_dsp_is_available())
+ return -EINVAL;
+
+ return platform_driver_register(&fsl_dsp_driver);
+}
+module_init(fsl_dsp_driver_init);
+
+static void __exit fsl_dsp_driver_exit(void)
+{
+ platform_driver_unregister(&fsl_dsp_driver);
+}
+module_exit(fsl_dsp_driver_exit);
MODULE_DESCRIPTION("Freescale DSP driver");
MODULE_ALIAS("platform:fsl-dsp");
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d9958a52e871..ec572612bb50 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -73,6 +73,17 @@ static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
.constrain_period_size = false,
};
+static struct fsl_sai_soc_data fsl_sai_imx8mp = {
+ .imx = true,
+ .dataline = 0xff,
+ .fifos = 8,
+ .fifo_depth = 128,
+ .flags = 0,
+ .reg_offset = 8,
+ .constrain_period_size = false,
+ .mclk_gated_by_bce = true,
+};
+
static struct fsl_sai_soc_data fsl_sai_imx8mq = {
.imx = true,
.dataline = 0xff,
@@ -782,6 +793,18 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
FSL_SAI_CR5_FBT_MASK, val_cr5);
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
~0UL - ((1 << min(channels, slots)) - 1));
+
+ /*
+ * Some audio codecs need the MCLK during setup of the codec, however
+ * for the i.MX 8M Plus it is gated with the receiver/transmiter BCE
+ * bit. So enable the bit already here.
+ */
+ if (sai->soc->mclk_gated_by_bce) {
+ /* Switch on MCLK early */
+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
+ FSL_SAI_CSR_BCE, FSL_SAI_CSR_BCE);
+ }
+
return 0;
}
@@ -1270,6 +1293,7 @@ static const struct of_device_id fsl_sai_ids[] = {
{ .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx },
{ .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul },
{ .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp },
+ { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp },
{ .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq },
{ .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm },
{ /* sentinel */ }
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 8476cfffaa25..54e491182db8 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -89,6 +89,7 @@
/* SAI Transmit/Receive Control Register */
#define FSL_SAI_CSR_TERE BIT(31)
#define FSL_SAI_CSR_SE BIT(30)
+#define FSL_SAI_CSR_BCE BIT(28)
#define FSL_SAI_CSR_FR BIT(25)
#define FSL_SAI_CSR_SR BIT(24)
#define FSL_SAI_CSR_xF_SHIFT 16
@@ -225,6 +226,8 @@ struct fsl_sai_soc_data {
bool imx;
/* True for EDMA because it needs period size multiple of maxburst */
bool constrain_period_size;
+ /* Set to true if the MCLK to the output pin is gated with bce */
+ bool mclk_gated_by_bce;
};
struct fsl_sai_verid {
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 49f5a8551143..07f9ae81861c 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -530,10 +530,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
scr = SCR_TXFIFO_AUTOSYNC | SCR_TXFIFO_CTRL_NORMAL |
SCR_TXSEL_NORMAL | SCR_USRC_SEL_CHIP |
- SCR_TXFIFO_FSEL_IF8;
+ SCR_TXFIFO_FSEL_IF8 | SCR_VAL_CLEAR;
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
- SCR_TXFIFO_FSEL_MASK;
+ SCR_TXFIFO_FSEL_MASK | SCR_VAL_MASK;
} else {
scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
@@ -1525,12 +1525,20 @@ static int fsl_spdif_probe(struct platform_device *pdev)
&spdif_priv->cpu_dai_drv, 1);
if (ret) {
dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
- return ret;
+ goto disable_pm_runtime;
}
ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE);
- if (ret && ret != -EPROBE_DEFER)
- dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
+ goto disable_pm_runtime;
+ }
+
+ return 0;
+
+disable_pm_runtime:
+ pm_runtime_disable(&pdev->dev);
return ret;
}