linux/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * mach-imx27_visstrim_m10.c
   4 *
   5 * Copyright 2010  Javier Martin <javier.martin@vista-silicon.com>
   6 *
   7 * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others.
   8 */
   9
  10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/platform_device.h>
  13#include <linux/mtd/physmap.h>
  14#include <linux/i2c.h>
  15#include <linux/platform_data/pca953x.h>
  16#include <linux/input.h>
  17#include <linux/gpio.h>
  18#include <linux/delay.h>
  19#include <linux/dma-mapping.h>
  20#include <linux/leds.h>
  21#include <linux/platform_data/asoc-mx27vis.h>
  22#include <sound/tlv320aic32x4.h>
  23#include <asm/mach-types.h>
  24#include <asm/mach/arch.h>
  25#include <asm/mach/time.h>
  26#include <asm/system_info.h>
  27#include <asm/memblock.h>
  28
  29#include "common.h"
  30#include "devices-imx27.h"
  31#include "ehci.h"
  32#include "hardware.h"
  33#include "iomux-mx27.h"
  34
  35#define TVP5150_RSTN (GPIO_PORTC + 18)
  36#define TVP5150_PWDN (GPIO_PORTC + 19)
  37#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
  38#define SDHC1_IRQ_GPIO IMX_GPIO_NR(2, 25)
  39
  40#define VERSION_MASK            0x7
  41#define MOTHERBOARD_SHIFT       4
  42#define EXPBOARD_SHIFT          0
  43
  44#define MOTHERBOARD_BIT2        (GPIO_PORTD + 31)
  45#define MOTHERBOARD_BIT1        (GPIO_PORTD + 30)
  46#define MOTHERBOARD_BIT0        (GPIO_PORTD + 29)
  47
  48#define EXPBOARD_BIT2           (GPIO_PORTD + 25)
  49#define EXPBOARD_BIT1           (GPIO_PORTD + 27)
  50#define EXPBOARD_BIT0           (GPIO_PORTD + 28)
  51
  52#define AMP_GAIN_0              (GPIO_PORTF + 9)
  53#define AMP_GAIN_1              (GPIO_PORTF + 8)
  54#define AMP_MUTE_SDL            (GPIO_PORTE + 5)
  55#define AMP_MUTE_SDR            (GPIO_PORTF + 7)
  56
  57static const int visstrim_m10_pins[] __initconst = {
  58        /* UART1 (console) */
  59        PE12_PF_UART1_TXD,
  60        PE13_PF_UART1_RXD,
  61        PE14_PF_UART1_CTS,
  62        PE15_PF_UART1_RTS,
  63        /* FEC */
  64        PD0_AIN_FEC_TXD0,
  65        PD1_AIN_FEC_TXD1,
  66        PD2_AIN_FEC_TXD2,
  67        PD3_AIN_FEC_TXD3,
  68        PD4_AOUT_FEC_RX_ER,
  69        PD5_AOUT_FEC_RXD1,
  70        PD6_AOUT_FEC_RXD2,
  71        PD7_AOUT_FEC_RXD3,
  72        PD8_AF_FEC_MDIO,
  73        PD9_AIN_FEC_MDC,
  74        PD10_AOUT_FEC_CRS,
  75        PD11_AOUT_FEC_TX_CLK,
  76        PD12_AOUT_FEC_RXD0,
  77        PD13_AOUT_FEC_RX_DV,
  78        PD14_AOUT_FEC_RX_CLK,
  79        PD15_AOUT_FEC_COL,
  80        PD16_AIN_FEC_TX_ER,
  81        PF23_AIN_FEC_TX_EN,
  82        /* SSI1 */
  83        PC20_PF_SSI1_FS,
  84        PC21_PF_SSI1_RXD,
  85        PC22_PF_SSI1_TXD,
  86        PC23_PF_SSI1_CLK,
  87        /* SDHC1 */
  88        PE18_PF_SD1_D0,
  89        PE19_PF_SD1_D1,
  90        PE20_PF_SD1_D2,
  91        PE21_PF_SD1_D3,
  92        PE22_PF_SD1_CMD,
  93        PE23_PF_SD1_CLK,
  94        /* Both I2Cs */
  95        PD17_PF_I2C_DATA,
  96        PD18_PF_I2C_CLK,
  97        PC5_PF_I2C2_SDA,
  98        PC6_PF_I2C2_SCL,
  99        /* USB OTG */
 100        OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
 101        PC9_PF_USBOTG_DATA0,
 102        PC11_PF_USBOTG_DATA1,
 103        PC10_PF_USBOTG_DATA2,
 104        PC13_PF_USBOTG_DATA3,
 105        PC12_PF_USBOTG_DATA4,
 106        PC7_PF_USBOTG_DATA5,
 107        PC8_PF_USBOTG_DATA6,
 108        PE25_PF_USBOTG_DATA7,
 109        PE24_PF_USBOTG_CLK,
 110        PE2_PF_USBOTG_DIR,
 111        PE0_PF_USBOTG_NXT,
 112        PE1_PF_USBOTG_STP,
 113        PB23_PF_USB_PWR,
 114        PB24_PF_USB_OC,
 115        /* CSI */
 116        TVP5150_RSTN | GPIO_GPIO | GPIO_OUT,
 117        TVP5150_PWDN | GPIO_GPIO | GPIO_OUT,
 118        PB10_PF_CSI_D0,
 119        PB11_PF_CSI_D1,
 120        PB12_PF_CSI_D2,
 121        PB13_PF_CSI_D3,
 122        PB14_PF_CSI_D4,
 123        PB15_PF_CSI_MCLK,
 124        PB16_PF_CSI_PIXCLK,
 125        PB17_PF_CSI_D5,
 126        PB18_PF_CSI_D6,
 127        PB19_PF_CSI_D7,
 128        PB20_PF_CSI_VSYNC,
 129        PB21_PF_CSI_HSYNC,
 130        /* mother board version */
 131        MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 132        MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 133        MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 134        /* expansion board version */
 135        EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 136        EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 137        EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 138        /* Audio AMP control */
 139        AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT,
 140        AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT,
 141        AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT,
 142        AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT,
 143};
 144
 145static struct gpio visstrim_m10_version_gpios[] = {
 146        { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" },
 147        { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" },
 148        { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" },
 149        { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" },
 150        { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" },
 151        { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" },
 152};
 153
 154static const struct gpio visstrim_m10_gpios[] __initconst = {
 155        {
 156                .gpio = TVP5150_RSTN,
 157                .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH,
 158                .label = "tvp5150_rstn",
 159        },
 160        {
 161                .gpio = TVP5150_PWDN,
 162                .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
 163                .label = "tvp5150_pwdn",
 164        },
 165        {
 166                .gpio = OTG_PHY_CS_GPIO,
 167                .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
 168                .label = "usbotg_cs",
 169        },
 170        {
 171                .gpio = AMP_GAIN_0,
 172                .flags = GPIOF_DIR_OUT,
 173                .label = "amp-gain-0",
 174        },
 175        {
 176                .gpio = AMP_GAIN_1,
 177                .flags = GPIOF_DIR_OUT,
 178                .label = "amp-gain-1",
 179        },
 180        {
 181                .gpio = AMP_MUTE_SDL,
 182                .flags = GPIOF_DIR_OUT,
 183                .label = "amp-mute-sdl",
 184        },
 185        {
 186                .gpio = AMP_MUTE_SDR,
 187                .flags = GPIOF_DIR_OUT,
 188                .label = "amp-mute-sdr",
 189        },
 190};
 191
 192/* Camera */
 193static struct mx2_camera_platform_data visstrim_camera = {
 194        .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
 195                 MX2_CAMERA_PCLK_SAMPLE_RISING,
 196        .clk = 100000,
 197};
 198
 199static phys_addr_t mx2_camera_base __initdata;
 200#define MX2_CAMERA_BUF_SIZE SZ_8M
 201
 202static void __init visstrim_analog_camera_init(void)
 203{
 204        struct platform_device *pdev;
 205
 206        gpio_set_value(TVP5150_PWDN, 1);
 207        ndelay(1);
 208        gpio_set_value(TVP5150_RSTN, 0);
 209        ndelay(500);
 210        gpio_set_value(TVP5150_RSTN, 1);
 211        ndelay(200000);
 212
 213        pdev = imx27_add_mx2_camera(&visstrim_camera);
 214        if (IS_ERR(pdev))
 215                return;
 216
 217        dma_declare_coherent_memory(&pdev->dev, mx2_camera_base,
 218                                    mx2_camera_base, MX2_CAMERA_BUF_SIZE);
 219}
 220
 221static void __init visstrim_reserve(void)
 222{
 223        /* reserve 4 MiB for mx2-camera */
 224        mx2_camera_base = arm_memblock_steal(3 * MX2_CAMERA_BUF_SIZE,
 225                        MX2_CAMERA_BUF_SIZE);
 226}
 227
 228/* GPIOs used as events for applications */
 229static struct gpio_keys_button visstrim_gpio_keys[] = {
 230        {
 231                .type   = EV_KEY,
 232                .code   = KEY_RESTART,
 233                .gpio   = (GPIO_PORTC + 15),
 234                .desc   = "Default config",
 235                .active_low = 0,
 236                .wakeup = 1,
 237        },
 238        {
 239                .type   = EV_KEY,
 240                .code   = KEY_RECORD,
 241                .gpio   = (GPIO_PORTF + 14),
 242                .desc   = "Record",
 243                .active_low = 0,
 244                .wakeup = 1,
 245        },
 246        {
 247                .type   = EV_KEY,
 248                .code   = KEY_STOP,
 249                .gpio   = (GPIO_PORTF + 13),
 250                .desc   = "Stop",
 251                .active_low = 0,
 252                .wakeup = 1,
 253        }
 254};
 255
 256static const struct gpio_keys_platform_data
 257                visstrim_gpio_keys_platform_data __initconst = {
 258        .buttons        = visstrim_gpio_keys,
 259        .nbuttons       = ARRAY_SIZE(visstrim_gpio_keys),
 260};
 261
 262/* led */
 263static const struct gpio_led visstrim_m10_leds[] __initconst = {
 264        {
 265                .name = "visstrim:ld0",
 266                .default_trigger = "nand-disk",
 267                .gpio = (GPIO_PORTC + 29),
 268        },
 269        {
 270                .name = "visstrim:ld1",
 271                .default_trigger = "nand-disk",
 272                .gpio = (GPIO_PORTC + 24),
 273        },
 274        {
 275                .name = "visstrim:ld2",
 276                .default_trigger = "nand-disk",
 277                .gpio = (GPIO_PORTC + 28),
 278        },
 279        {
 280                .name = "visstrim:ld3",
 281                .default_trigger = "nand-disk",
 282                .gpio = (GPIO_PORTC + 25),
 283        },
 284};
 285
 286static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = {
 287        .leds = visstrim_m10_leds,
 288        .num_leds = ARRAY_SIZE(visstrim_m10_leds),
 289};
 290
 291/* Visstrim_SM10 has a microSD slot connected to sdhc1 */
 292static int visstrim_m10_sdhc1_init(struct device *dev,
 293                irq_handler_t detect_irq, void *data)
 294{
 295        int ret;
 296
 297        ret = request_irq(gpio_to_irq(SDHC1_IRQ_GPIO), detect_irq,
 298                          IRQF_TRIGGER_FALLING, "mmc-detect", data);
 299        return ret;
 300}
 301
 302static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
 303{
 304        free_irq(gpio_to_irq(SDHC1_IRQ_GPIO), data);
 305}
 306
 307static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = {
 308        .init = visstrim_m10_sdhc1_init,
 309        .exit = visstrim_m10_sdhc1_exit,
 310};
 311
 312/* Visstrim_SM10 NOR flash */
 313static struct physmap_flash_data visstrim_m10_flash_data = {
 314        .width = 2,
 315};
 316
 317static struct resource visstrim_m10_flash_resource = {
 318        .start = 0xc0000000,
 319        .end = 0xc0000000 + SZ_64M - 1,
 320        .flags = IORESOURCE_MEM,
 321};
 322
 323static struct platform_device visstrim_m10_nor_mtd_device = {
 324        .name = "physmap-flash",
 325        .id = 0,
 326        .dev = {
 327                .platform_data = &visstrim_m10_flash_data,
 328        },
 329        .num_resources = 1,
 330        .resource = &visstrim_m10_flash_resource,
 331};
 332
 333static struct platform_device *platform_devices[] __initdata = {
 334        &visstrim_m10_nor_mtd_device,
 335};
 336
 337/* Visstrim_M10 uses UART0 as console */
 338static const struct imxuart_platform_data uart_pdata __initconst = {
 339        .flags = IMXUART_HAVE_RTSCTS,
 340};
 341
 342/* I2C */
 343static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = {
 344        .bitrate = 100000,
 345};
 346
 347static struct pca953x_platform_data visstrim_m10_pca9555_pdata = {
 348        .gpio_base = 240, /* After MX27 internal GPIOs */
 349        .invert = 0,
 350};
 351
 352static struct aic32x4_pdata visstrim_m10_aic32x4_pdata = {
 353        .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN |
 354                     AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE |
 355                     AIC32X4_PWR_AIC32X4_LDO_ENABLE |
 356                     AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 |
 357                     AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED,
 358        .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K |
 359                         AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K,
 360        .swapdacs = false,
 361};
 362
 363static struct i2c_board_info visstrim_m10_i2c_devices[] = {
 364        {
 365                I2C_BOARD_INFO("pca9555", 0x20),
 366                .platform_data = &visstrim_m10_pca9555_pdata,
 367        },
 368        {
 369                I2C_BOARD_INFO("tlv320aic32x4", 0x18),
 370                .platform_data = &visstrim_m10_aic32x4_pdata,
 371        },
 372        {
 373                 I2C_BOARD_INFO("m41t00", 0x68),
 374        }
 375};
 376
 377/* USB OTG */
 378static int otg_phy_init(struct platform_device *pdev)
 379{
 380        return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
 381}
 382
 383static const struct mxc_usbh_platform_data
 384visstrim_m10_usbotg_pdata __initconst = {
 385        .init = otg_phy_init,
 386        .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
 387};
 388
 389/* SSI */
 390static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
 391        .flags                  = IMX_SSI_DMA | IMX_SSI_SYN,
 392};
 393
 394/* coda */
 395
 396static void __init visstrim_coda_init(void)
 397{
 398        struct platform_device *pdev;
 399
 400        pdev = imx27_add_coda();
 401        dma_declare_coherent_memory(&pdev->dev,
 402                                    mx2_camera_base + MX2_CAMERA_BUF_SIZE,
 403                                    mx2_camera_base + MX2_CAMERA_BUF_SIZE,
 404                                    MX2_CAMERA_BUF_SIZE);
 405}
 406
 407/* DMA deinterlace */
 408static struct platform_device visstrim_deinterlace = {
 409        .name = "m2m-deinterlace",
 410        .id = 0,
 411};
 412
 413static void __init visstrim_deinterlace_init(void)
 414{
 415        int ret = -ENOMEM;
 416        struct platform_device *pdev = &visstrim_deinterlace;
 417
 418        ret = platform_device_register(pdev);
 419
 420        dma_declare_coherent_memory(&pdev->dev,
 421                                    mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
 422                                    mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
 423                                    MX2_CAMERA_BUF_SIZE);
 424}
 425
 426/* Emma-PrP for format conversion */
 427static void __init visstrim_emmaprp_init(void)
 428{
 429        struct platform_device *pdev;
 430        int ret;
 431
 432        pdev = imx27_add_mx2_emmaprp();
 433        if (IS_ERR(pdev))
 434                return;
 435
 436        /*
 437         * Use the same memory area as the analog camera since both
 438         * devices are, by nature, exclusive.
 439         */
 440        ret = dma_declare_coherent_memory(&pdev->dev,
 441                                mx2_camera_base, mx2_camera_base,
 442                                MX2_CAMERA_BUF_SIZE);
 443        if (ret)
 444                pr_err("Failed to declare memory for emmaprp\n");
 445}
 446
 447/* Audio */
 448static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = {
 449        .amp_gain0_gpio = AMP_GAIN_0,
 450        .amp_gain1_gpio = AMP_GAIN_1,
 451        .amp_mutel_gpio = AMP_MUTE_SDL,
 452        .amp_muter_gpio = AMP_MUTE_SDR,
 453};
 454
 455static void __init visstrim_m10_revision(void)
 456{
 457        int exp_version = 0;
 458        int mo_version = 0;
 459        int ret;
 460
 461        ret = gpio_request_array(visstrim_m10_version_gpios,
 462                                 ARRAY_SIZE(visstrim_m10_version_gpios));
 463        if (ret) {
 464                pr_err("Failed to request version gpios");
 465                return;
 466        }
 467
 468        /* Get expansion board version (negative logic) */
 469        exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2;
 470        exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1;
 471        exp_version |= !gpio_get_value(EXPBOARD_BIT0);
 472
 473        /* Get mother board version (negative logic) */
 474        mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2;
 475        mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1;
 476        mo_version |= !gpio_get_value(MOTHERBOARD_BIT0);
 477
 478        system_rev = 0x27000;
 479        system_rev |= (mo_version << MOTHERBOARD_SHIFT);
 480        system_rev |= (exp_version << EXPBOARD_SHIFT);
 481}
 482
 483static void __init visstrim_m10_board_init(void)
 484{
 485        int ret;
 486
 487        imx27_soc_init();
 488        visstrim_m10_revision();
 489
 490        ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
 491                        ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
 492        if (ret)
 493                pr_err("Failed to setup pins (%d)\n", ret);
 494
 495        imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
 496        imx27_add_imx_uart0(&uart_pdata);
 497
 498        imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
 499        imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
 500        i2c_register_board_info(0, visstrim_m10_i2c_devices,
 501                                ARRAY_SIZE(visstrim_m10_i2c_devices));
 502
 503        imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
 504        imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
 505        imx27_add_fec(NULL);
 506
 507        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 508}
 509
 510static void __init visstrim_m10_late_init(void)
 511{
 512        int mo_version, ret;
 513
 514        ret = gpio_request_array(visstrim_m10_gpios,
 515                                 ARRAY_SIZE(visstrim_m10_gpios));
 516        if (ret)
 517                pr_err("Failed to request gpios (%d)\n", ret);
 518
 519        imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
 520
 521        imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
 522                                sizeof(snd_mx27vis_pdata));
 523
 524        gpio_led_register_device(0, &visstrim_m10_led_data);
 525
 526        /* Use mother board version to decide what video devices we shall use */
 527        mo_version = (system_rev >> MOTHERBOARD_SHIFT) & VERSION_MASK;
 528        if (mo_version & 0x1) {
 529                visstrim_emmaprp_init();
 530
 531                /*
 532                 * Despite not being used, tvp5150 must be
 533                 * powered on to avoid I2C problems. To minimize
 534                 * power consupmtion keep reset enabled.
 535                 */
 536                gpio_set_value(TVP5150_PWDN, 1);
 537                ndelay(1);
 538                gpio_set_value(TVP5150_RSTN, 0);
 539        } else {
 540                visstrim_deinterlace_init();
 541                visstrim_analog_camera_init();
 542        }
 543
 544        visstrim_coda_init();
 545}
 546
 547static void __init visstrim_m10_timer_init(void)
 548{
 549        mx27_clocks_init((unsigned long)25000000);
 550}
 551
 552MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
 553        .atag_offset = 0x100,
 554        .reserve = visstrim_reserve,
 555        .map_io = mx27_map_io,
 556        .init_early = imx27_init_early,
 557        .init_irq = mx27_init_irq,
 558        .init_time      = visstrim_m10_timer_init,
 559        .init_machine = visstrim_m10_board_init,
 560        .init_late      = visstrim_m10_late_init,
 561        .restart        = mxc_restart,
 562MACHINE_END
 563