linux/arch/arm/mach-imx/pcm970-baseboard.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version 2
   7 * of the License, or (at your option) any later version.
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software
  15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16 * MA 02110-1301, USA.
  17 */
  18
  19#include <linux/gpio.h>
  20#include <linux/irq.h>
  21#include <linux/platform_device.h>
  22#include <linux/can/platform/sja1000.h>
  23
  24#include <asm/mach/arch.h>
  25
  26#include "common.h"
  27#include "devices-imx27.h"
  28#include "hardware.h"
  29#include "iomux-mx27.h"
  30
  31static const int pcm970_pins[] __initconst = {
  32        /* SDHC */
  33        PB4_PF_SD2_D0,
  34        PB5_PF_SD2_D1,
  35        PB6_PF_SD2_D2,
  36        PB7_PF_SD2_D3,
  37        PB8_PF_SD2_CMD,
  38        PB9_PF_SD2_CLK,
  39        /* display */
  40        PA5_PF_LSCLK,
  41        PA6_PF_LD0,
  42        PA7_PF_LD1,
  43        PA8_PF_LD2,
  44        PA9_PF_LD3,
  45        PA10_PF_LD4,
  46        PA11_PF_LD5,
  47        PA12_PF_LD6,
  48        PA13_PF_LD7,
  49        PA14_PF_LD8,
  50        PA15_PF_LD9,
  51        PA16_PF_LD10,
  52        PA17_PF_LD11,
  53        PA18_PF_LD12,
  54        PA19_PF_LD13,
  55        PA20_PF_LD14,
  56        PA21_PF_LD15,
  57        PA22_PF_LD16,
  58        PA23_PF_LD17,
  59        PA24_PF_REV,
  60        PA25_PF_CLS,
  61        PA26_PF_PS,
  62        PA27_PF_SPL_SPR,
  63        PA28_PF_HSYNC,
  64        PA29_PF_VSYNC,
  65        PA30_PF_CONTRAST,
  66        PA31_PF_OE_ACD,
  67        /*
  68         * it seems the data line misses a pullup, so we must enable
  69         * the internal pullup as a local workaround
  70         */
  71        PD17_PF_I2C_DATA | GPIO_PUEN,
  72        PD18_PF_I2C_CLK,
  73        /* Camera */
  74        PB10_PF_CSI_D0,
  75        PB11_PF_CSI_D1,
  76        PB12_PF_CSI_D2,
  77        PB13_PF_CSI_D3,
  78        PB14_PF_CSI_D4,
  79        PB15_PF_CSI_MCLK,
  80        PB16_PF_CSI_PIXCLK,
  81        PB17_PF_CSI_D5,
  82        PB18_PF_CSI_D6,
  83        PB19_PF_CSI_D7,
  84        PB20_PF_CSI_VSYNC,
  85        PB21_PF_CSI_HSYNC,
  86};
  87
  88static int pcm970_sdhc2_get_ro(struct device *dev)
  89{
  90        return gpio_get_value(GPIO_PORTC + 28);
  91}
  92
  93static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
  94{
  95        int ret;
  96
  97        ret = request_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), detect_irq,
  98                          IRQF_TRIGGER_FALLING, "imx-mmc-detect", data);
  99        if (ret)
 100                return ret;
 101
 102        ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
 103        if (ret) {
 104                free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data);
 105                return ret;
 106        }
 107
 108        gpio_direction_input(GPIO_PORTC + 28);
 109
 110        return 0;
 111}
 112
 113static void pcm970_sdhc2_exit(struct device *dev, void *data)
 114{
 115        free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data);
 116        gpio_free(GPIO_PORTC + 28);
 117}
 118
 119static const struct imxmmc_platform_data sdhc_pdata __initconst = {
 120        .get_ro = pcm970_sdhc2_get_ro,
 121        .init = pcm970_sdhc2_init,
 122        .exit = pcm970_sdhc2_exit,
 123};
 124
 125static struct imx_fb_videomode pcm970_modes[] = {
 126        {
 127                .mode = {
 128                        .name           = "Sharp-LQ035Q7",
 129                        .refresh        = 60,
 130                        .xres           = 240,
 131                        .yres           = 320,
 132                        .pixclock       = 188679, /* in ps (5.3MHz) */
 133                        .hsync_len      = 7,
 134                        .left_margin    = 5,
 135                        .right_margin   = 16,
 136                        .vsync_len      = 1,
 137                        .upper_margin   = 7,
 138                        .lower_margin   = 9,
 139                },
 140                /*
 141                 * - HSYNC active high
 142                 * - VSYNC active high
 143                 * - clk notenabled while idle
 144                 * - clock not inverted
 145                 * - data not inverted
 146                 * - data enable low active
 147                 * - enable sharp mode
 148                 */
 149                .pcr            = 0xF00080C0,
 150                .bpp            = 16,
 151        }, {
 152                .mode = {
 153                        .name           = "TX090",
 154                        .refresh        = 60,
 155                        .xres           = 240,
 156                        .yres           = 320,
 157                        .pixclock       = 38255,
 158                        .left_margin    = 144,
 159                        .right_margin   = 0,
 160                        .upper_margin   = 7,
 161                        .lower_margin   = 40,
 162                        .hsync_len      = 96,
 163                        .vsync_len      = 1,
 164                },
 165                /*
 166                 * - HSYNC active low (1 << 22)
 167                 * - VSYNC active low (1 << 23)
 168                 * - clk notenabled while idle
 169                 * - clock not inverted
 170                 * - data not inverted
 171                 * - data enable low active
 172                 * - enable sharp mode
 173                 */
 174                .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
 175                .bpp = 32,
 176        },
 177};
 178
 179static const struct imx_fb_platform_data pcm038_fb_data __initconst = {
 180        .mode = pcm970_modes,
 181        .num_modes = ARRAY_SIZE(pcm970_modes),
 182
 183        .pwmr           = 0x00A903FF,
 184        .lscr1          = 0x00120300,
 185        .dmacr          = 0x00020010,
 186};
 187
 188static struct resource pcm970_sja1000_resources[] = {
 189        {
 190                .start   = MX27_CS4_BASE_ADDR,
 191                .end     = MX27_CS4_BASE_ADDR + 0x100 - 1,
 192                .flags   = IORESOURCE_MEM,
 193        }, {
 194                /* irq number is run-time assigned */
 195                .flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 196        },
 197};
 198
 199static struct sja1000_platform_data pcm970_sja1000_platform_data = {
 200        .osc_freq       = 16000000,
 201        .ocr            = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
 202        .cdr            = CDR_CBP,
 203};
 204
 205static struct platform_device pcm970_sja1000 = {
 206        .name = "sja1000_platform",
 207        .dev = {
 208                .platform_data = &pcm970_sja1000_platform_data,
 209        },
 210        .resource = pcm970_sja1000_resources,
 211        .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
 212};
 213
 214/*
 215 * system init for baseboard usage. Will be called by pcm038 init.
 216 *
 217 * Add platform devices present on this baseboard and init
 218 * them from CPU side as far as required to use them later on
 219 */
 220void __init pcm970_baseboard_init(void)
 221{
 222        mxc_gpio_setup_multiple_pins(pcm970_pins, ARRAY_SIZE(pcm970_pins),
 223                        "PCM970");
 224
 225        imx27_add_imx_fb(&pcm038_fb_data);
 226        mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
 227        imx27_add_mxc_mmc(1, &sdhc_pdata);
 228        pcm970_sja1000_resources[1].start = gpio_to_irq(IMX_GPIO_NR(5, 19));
 229        pcm970_sja1000_resources[1].end = gpio_to_irq(IMX_GPIO_NR(5, 19));
 230        platform_device_register(&pcm970_sja1000);
 231}
 232