1 /* 2 * TI DaVinci DM365 EVM board support 3 * 4 * Copyright (C) 2009 Texas Instruments Incorporated 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/err.h> 18 #include <linux/i2c.h> 19 #include <linux/io.h> 20 #include <linux/clk.h> 21 #include <linux/property.h> 22 #include <linux/leds.h> 23 #include <linux/mtd/mtd.h> 24 #include <linux/mtd/partitions.h> 25 #include <linux/slab.h> 26 #include <linux/mtd/rawnand.h> 27 #include <linux/nvmem-provider.h> 28 #include <linux/input.h> 29 #include <linux/spi/spi.h> 30 #include <linux/spi/eeprom.h> 31 #include <linux/v4l2-dv-timings.h> 32 #include <linux/platform_data/ti-aemif.h> 33 34 #include <asm/mach-types.h> 35 #include <asm/mach/arch.h> 36 37 #include <mach/mux.h> 38 #include <mach/common.h> 39 #include <linux/platform_data/i2c-davinci.h> 40 #include <mach/serial.h> 41 #include <linux/platform_data/mmc-davinci.h> 42 #include <linux/platform_data/mtd-davinci.h> 43 #include <linux/platform_data/keyscan-davinci.h> 44 45 #include <media/i2c/ths7303.h> 46 #include <media/i2c/tvp514x.h> 47 48 #include "davinci.h" 49 50 static inline int have_imager(void) 51 { 52 /* REVISIT when it's supported, trigger via Kconfig */ 53 return 0; 54 } 55 56 static inline int have_tvp7002(void) 57 { 58 /* REVISIT when it's supported, trigger via Kconfig */ 59 return 0; 60 } 61 62 #define DM365_EVM_PHY_ID "davinci_mdio-0:01" 63 /* 64 * A MAX-II CPLD is used for various board control functions. 65 */ 66 #define CPLD_OFFSET(a13a8,a2a1) (((a13a8) << 10) + ((a2a1) << 3)) 67 68 #define CPLD_VERSION CPLD_OFFSET(0,0) /* r/o */ 69 #define CPLD_TEST CPLD_OFFSET(0,1) 70 #define CPLD_LEDS CPLD_OFFSET(0,2) 71 #define CPLD_MUX CPLD_OFFSET(0,3) 72 #define CPLD_SWITCH CPLD_OFFSET(1,0) /* r/o */ 73 #define CPLD_POWER CPLD_OFFSET(1,1) 74 #define CPLD_VIDEO CPLD_OFFSET(1,2) 75 #define CPLD_CARDSTAT CPLD_OFFSET(1,3) /* r/o */ 76 77 #define CPLD_DILC_OUT CPLD_OFFSET(2,0) 78 #define CPLD_DILC_IN CPLD_OFFSET(2,1) /* r/o */ 79 80 #define CPLD_IMG_DIR0 CPLD_OFFSET(2,2) 81 #define CPLD_IMG_MUX0 CPLD_OFFSET(2,3) 82 #define CPLD_IMG_MUX1 CPLD_OFFSET(3,0) 83 #define CPLD_IMG_DIR1 CPLD_OFFSET(3,1) 84 #define CPLD_IMG_MUX2 CPLD_OFFSET(3,2) 85 #define CPLD_IMG_MUX3 CPLD_OFFSET(3,3) 86 #define CPLD_IMG_DIR2 CPLD_OFFSET(4,0) 87 #define CPLD_IMG_MUX4 CPLD_OFFSET(4,1) 88 #define CPLD_IMG_MUX5 CPLD_OFFSET(4,2) 89 90 #define CPLD_RESETS CPLD_OFFSET(4,3) 91 92 #define CPLD_CCD_DIR1 CPLD_OFFSET(0x3e,0) 93 #define CPLD_CCD_IO1 CPLD_OFFSET(0x3e,1) 94 #define CPLD_CCD_DIR2 CPLD_OFFSET(0x3e,2) 95 #define CPLD_CCD_IO2 CPLD_OFFSET(0x3e,3) 96 #define CPLD_CCD_DIR3 CPLD_OFFSET(0x3f,0) 97 #define CPLD_CCD_IO3 CPLD_OFFSET(0x3f,1) 98 99 static void __iomem *cpld; 100 101 102 /* NOTE: this is geared for the standard config, with a socketed 103 * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you 104 * swap chips with a different block size, partitioning will 105 * need to be changed. This NAND chip MT29F16G08FAA is the default 106 * NAND shipped with the Spectrum Digital DM365 EVM 107 */ 108 #define NAND_BLOCK_SIZE SZ_128K 109 110 static struct mtd_partition davinci_nand_partitions[] = { 111 { 112 /* UBL (a few copies) plus U-Boot */ 113 .name = "bootloader", 114 .offset = 0, 115 .size = 30 * NAND_BLOCK_SIZE, 116 .mask_flags = MTD_WRITEABLE, /* force read-only */ 117 }, { 118 /* U-Boot environment */ 119 .name = "params", 120 .offset = MTDPART_OFS_APPEND, 121 .size = 2 * NAND_BLOCK_SIZE, 122 .mask_flags = 0, 123 }, { 124 .name = "kernel", 125 .offset = MTDPART_OFS_APPEND, 126 .size = SZ_4M, 127 .mask_flags = 0, 128 }, { 129 .name = "filesystem1", 130 .offset = MTDPART_OFS_APPEND, 131 .size = SZ_512M, 132 .mask_flags = 0, 133 }, { 134 .name = "filesystem2", 135 .offset = MTDPART_OFS_APPEND, 136 .size = MTDPART_SIZ_FULL, 137 .mask_flags = 0, 138 } 139 /* two blocks with bad block table (and mirror) at the end */ 140 }; 141 142 static struct davinci_nand_pdata davinci_nand_data = { 143 .core_chipsel = 0, 144 .mask_chipsel = BIT(14), 145 .parts = davinci_nand_partitions, 146 .nr_parts = ARRAY_SIZE(davinci_nand_partitions), 147 .ecc_mode = NAND_ECC_HW, 148 .bbt_options = NAND_BBT_USE_FLASH, 149 .ecc_bits = 4, 150 }; 151 152 static struct resource davinci_nand_resources[] = { 153 { 154 .start = DM365_ASYNC_EMIF_DATA_CE0_BASE, 155 .end = DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, 156 .flags = IORESOURCE_MEM, 157 }, { 158 .start = DM365_ASYNC_EMIF_CONTROL_BASE, 159 .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, 160 .flags = IORESOURCE_MEM, 161 }, 162 }; 163 164 static struct platform_device davinci_aemif_devices[] = { 165 { 166 .name = "davinci_nand", 167 .id = 0, 168 .num_resources = ARRAY_SIZE(davinci_nand_resources), 169 .resource = davinci_nand_resources, 170 .dev = { 171 .platform_data = &davinci_nand_data, 172 }, 173 } 174 }; 175 176 static struct resource davinci_aemif_resources[] = { 177 { 178 .start = DM365_ASYNC_EMIF_CONTROL_BASE, 179 .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, 180 .flags = IORESOURCE_MEM, 181 }, 182 }; 183 184 static struct aemif_abus_data da850_evm_aemif_abus_data[] = { 185 { 186 .cs = 1, 187 }, 188 }; 189 190 static struct aemif_platform_data davinci_aemif_pdata = { 191 .abus_data = da850_evm_aemif_abus_data, 192 .num_abus_data = ARRAY_SIZE(da850_evm_aemif_abus_data), 193 .sub_devices = davinci_aemif_devices, 194 .num_sub_devices = ARRAY_SIZE(davinci_aemif_devices), 195 }; 196 197 static struct platform_device davinci_aemif_device = { 198 .name = "ti-aemif", 199 .id = -1, 200 .dev = { 201 .platform_data = &davinci_aemif_pdata, 202 }, 203 .resource = davinci_aemif_resources, 204 .num_resources = ARRAY_SIZE(davinci_aemif_resources), 205 }; 206 207 static struct nvmem_cell_info davinci_nvmem_cells[] = { 208 { 209 .name = "macaddr", 210 .offset = 0x7f00, 211 .bytes = ETH_ALEN, 212 } 213 }; 214 215 static struct nvmem_cell_table davinci_nvmem_cell_table = { 216 .nvmem_name = "1-00500", 217 .cells = davinci_nvmem_cells, 218 .ncells = ARRAY_SIZE(davinci_nvmem_cells), 219 }; 220 221 static struct nvmem_cell_lookup davinci_nvmem_cell_lookup = { 222 .nvmem_name = "1-00500", 223 .cell_name = "macaddr", 224 .dev_id = "davinci_emac.1", 225 .con_id = "mac-address", 226 }; 227 228 static const struct property_entry eeprom_properties[] = { 229 PROPERTY_ENTRY_U32("pagesize", 64), 230 { } 231 }; 232 233 static struct i2c_board_info i2c_info[] = { 234 { 235 I2C_BOARD_INFO("24c256", 0x50), 236 .properties = eeprom_properties, 237 }, 238 { 239 I2C_BOARD_INFO("tlv320aic3x", 0x18), 240 }, 241 }; 242 243 static struct davinci_i2c_platform_data i2c_pdata = { 244 .bus_freq = 400 /* kHz */, 245 .bus_delay = 0 /* usec */, 246 }; 247 248 static int dm365evm_keyscan_enable(struct device *dev) 249 { 250 return davinci_cfg_reg(DM365_KEYSCAN); 251 } 252 253 static unsigned short dm365evm_keymap[] = { 254 KEY_KP2, 255 KEY_LEFT, 256 KEY_EXIT, 257 KEY_DOWN, 258 KEY_ENTER, 259 KEY_UP, 260 KEY_KP1, 261 KEY_RIGHT, 262 KEY_MENU, 263 KEY_RECORD, 264 KEY_REWIND, 265 KEY_KPMINUS, 266 KEY_STOP, 267 KEY_FASTFORWARD, 268 KEY_KPPLUS, 269 KEY_PLAYPAUSE, 270 0 271 }; 272 273 static struct davinci_ks_platform_data dm365evm_ks_data = { 274 .device_enable = dm365evm_keyscan_enable, 275 .keymap = dm365evm_keymap, 276 .keymapsize = ARRAY_SIZE(dm365evm_keymap), 277 .rep = 1, 278 /* Scan period = strobe + interval */ 279 .strobe = 0x5, 280 .interval = 0x2, 281 .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4, 282 }; 283 284 static int cpld_mmc_get_cd(int module) 285 { 286 if (!cpld) 287 return -ENXIO; 288 289 /* low == card present */ 290 return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0)); 291 } 292 293 static int cpld_mmc_get_ro(int module) 294 { 295 if (!cpld) 296 return -ENXIO; 297 298 /* high == card's write protect switch active */ 299 return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1)); 300 } 301 302 static struct davinci_mmc_config dm365evm_mmc_config = { 303 .get_cd = cpld_mmc_get_cd, 304 .get_ro = cpld_mmc_get_ro, 305 .wires = 4, 306 .max_freq = 50000000, 307 .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, 308 }; 309 310 static void dm365evm_emac_configure(void) 311 { 312 /* 313 * EMAC pins are multiplexed with GPIO and UART 314 * Further details are available at the DM365 ARM 315 * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127 316 */ 317 davinci_cfg_reg(DM365_EMAC_TX_EN); 318 davinci_cfg_reg(DM365_EMAC_TX_CLK); 319 davinci_cfg_reg(DM365_EMAC_COL); 320 davinci_cfg_reg(DM365_EMAC_TXD3); 321 davinci_cfg_reg(DM365_EMAC_TXD2); 322 davinci_cfg_reg(DM365_EMAC_TXD1); 323 davinci_cfg_reg(DM365_EMAC_TXD0); 324 davinci_cfg_reg(DM365_EMAC_RXD3); 325 davinci_cfg_reg(DM365_EMAC_RXD2); 326 davinci_cfg_reg(DM365_EMAC_RXD1); 327 davinci_cfg_reg(DM365_EMAC_RXD0); 328 davinci_cfg_reg(DM365_EMAC_RX_CLK); 329 davinci_cfg_reg(DM365_EMAC_RX_DV); 330 davinci_cfg_reg(DM365_EMAC_RX_ER); 331 davinci_cfg_reg(DM365_EMAC_CRS); 332 davinci_cfg_reg(DM365_EMAC_MDIO); 333 davinci_cfg_reg(DM365_EMAC_MDCLK); 334 335 /* 336 * EMAC interrupts are multiplexed with GPIO interrupts 337 * Details are available at the DM365 ARM 338 * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134 339 */ 340 davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH); 341 davinci_cfg_reg(DM365_INT_EMAC_RXPULSE); 342 davinci_cfg_reg(DM365_INT_EMAC_TXPULSE); 343 davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE); 344 } 345 346 static void dm365evm_mmc_configure(void) 347 { 348 /* 349 * MMC/SD pins are multiplexed with GPIO and EMIF 350 * Further details are available at the DM365 ARM 351 * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131 352 */ 353 davinci_cfg_reg(DM365_SD1_CLK); 354 davinci_cfg_reg(DM365_SD1_CMD); 355 davinci_cfg_reg(DM365_SD1_DATA3); 356 davinci_cfg_reg(DM365_SD1_DATA2); 357 davinci_cfg_reg(DM365_SD1_DATA1); 358 davinci_cfg_reg(DM365_SD1_DATA0); 359 } 360 361 static struct tvp514x_platform_data tvp5146_pdata = { 362 .clk_polarity = 0, 363 .hs_polarity = 1, 364 .vs_polarity = 1 365 }; 366 367 #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) 368 /* Inputs available at the TVP5146 */ 369 static struct v4l2_input tvp5146_inputs[] = { 370 { 371 .index = 0, 372 .name = "Composite", 373 .type = V4L2_INPUT_TYPE_CAMERA, 374 .std = TVP514X_STD_ALL, 375 }, 376 { 377 .index = 1, 378 .name = "S-Video", 379 .type = V4L2_INPUT_TYPE_CAMERA, 380 .std = TVP514X_STD_ALL, 381 }, 382 }; 383 384 /* 385 * this is the route info for connecting each input to decoder 386 * ouput that goes to vpfe. There is a one to one correspondence 387 * with tvp5146_inputs 388 */ 389 static struct vpfe_route tvp5146_routes[] = { 390 { 391 .input = INPUT_CVBS_VI2B, 392 .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, 393 }, 394 { 395 .input = INPUT_SVIDEO_VI2C_VI1C, 396 .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, 397 }, 398 }; 399 400 static struct vpfe_subdev_info vpfe_sub_devs[] = { 401 { 402 .name = "tvp5146", 403 .grp_id = 0, 404 .num_inputs = ARRAY_SIZE(tvp5146_inputs), 405 .inputs = tvp5146_inputs, 406 .routes = tvp5146_routes, 407 .can_route = 1, 408 .ccdc_if_params = { 409 .if_type = VPFE_BT656, 410 .hdpol = VPFE_PINPOL_POSITIVE, 411 .vdpol = VPFE_PINPOL_POSITIVE, 412 }, 413 .board_info = { 414 I2C_BOARD_INFO("tvp5146", 0x5d), 415 .platform_data = &tvp5146_pdata, 416 }, 417 }, 418 }; 419 420 static struct vpfe_config vpfe_cfg = { 421 .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), 422 .sub_devs = vpfe_sub_devs, 423 .i2c_adapter_id = 1, 424 .card_name = "DM365 EVM", 425 .ccdc = "ISIF", 426 }; 427 428 /* venc standards timings */ 429 static struct vpbe_enc_mode_info dm365evm_enc_std_timing[] = { 430 { 431 .name = "ntsc", 432 .timings_type = VPBE_ENC_STD, 433 .std_id = V4L2_STD_NTSC, 434 .interlaced = 1, 435 .xres = 720, 436 .yres = 480, 437 .aspect = {11, 10}, 438 .fps = {30000, 1001}, 439 .left_margin = 0x79, 440 .upper_margin = 0x10, 441 }, 442 { 443 .name = "pal", 444 .timings_type = VPBE_ENC_STD, 445 .std_id = V4L2_STD_PAL, 446 .interlaced = 1, 447 .xres = 720, 448 .yres = 576, 449 .aspect = {54, 59}, 450 .fps = {25, 1}, 451 .left_margin = 0x7E, 452 .upper_margin = 0x16, 453 }, 454 }; 455 456 /* venc dv timings */ 457 static struct vpbe_enc_mode_info dm365evm_enc_preset_timing[] = { 458 { 459 .name = "480p59_94", 460 .timings_type = VPBE_ENC_DV_TIMINGS, 461 .dv_timings = V4L2_DV_BT_CEA_720X480P59_94, 462 .interlaced = 0, 463 .xres = 720, 464 .yres = 480, 465 .aspect = {1, 1}, 466 .fps = {5994, 100}, 467 .left_margin = 0x8F, 468 .upper_margin = 0x2D, 469 }, 470 { 471 .name = "576p50", 472 .timings_type = VPBE_ENC_DV_TIMINGS, 473 .dv_timings = V4L2_DV_BT_CEA_720X576P50, 474 .interlaced = 0, 475 .xres = 720, 476 .yres = 576, 477 .aspect = {1, 1}, 478 .fps = {50, 1}, 479 .left_margin = 0x8C, 480 .upper_margin = 0x36, 481 }, 482 { 483 .name = "720p60", 484 .timings_type = VPBE_ENC_DV_TIMINGS, 485 .dv_timings = V4L2_DV_BT_CEA_1280X720P60, 486 .interlaced = 0, 487 .xres = 1280, 488 .yres = 720, 489 .aspect = {1, 1}, 490 .fps = {60, 1}, 491 .left_margin = 0x117, 492 .right_margin = 70, 493 .upper_margin = 38, 494 .lower_margin = 3, 495 .hsync_len = 80, 496 .vsync_len = 5, 497 }, 498 { 499 .name = "1080i60", 500 .timings_type = VPBE_ENC_DV_TIMINGS, 501 .dv_timings = V4L2_DV_BT_CEA_1920X1080I60, 502 .interlaced = 1, 503 .xres = 1920, 504 .yres = 1080, 505 .aspect = {1, 1}, 506 .fps = {30, 1}, 507 .left_margin = 0xc9, 508 .right_margin = 80, 509 .upper_margin = 30, 510 .lower_margin = 3, 511 .hsync_len = 88, 512 .vsync_len = 5, 513 }, 514 }; 515 516 #define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) 517 518 /* 519 * The outputs available from VPBE + ecnoders. Keep the 520 * the order same as that of encoders. First those from venc followed by that 521 * from encoders. Index in the output refers to index on a particular 522 * encoder.Driver uses this index to pass it to encoder when it supports more 523 * than one output. Application uses index of the array to set an output. 524 */ 525 static struct vpbe_output dm365evm_vpbe_outputs[] = { 526 { 527 .output = { 528 .index = 0, 529 .name = "Composite", 530 .type = V4L2_OUTPUT_TYPE_ANALOG, 531 .std = VENC_STD_ALL, 532 .capabilities = V4L2_OUT_CAP_STD, 533 }, 534 .subdev_name = DM365_VPBE_VENC_SUBDEV_NAME, 535 .default_mode = "ntsc", 536 .num_modes = ARRAY_SIZE(dm365evm_enc_std_timing), 537 .modes = dm365evm_enc_std_timing, 538 .if_params = MEDIA_BUS_FMT_FIXED, 539 }, 540 { 541 .output = { 542 .index = 1, 543 .name = "Component", 544 .type = V4L2_OUTPUT_TYPE_ANALOG, 545 .capabilities = V4L2_OUT_CAP_DV_TIMINGS, 546 }, 547 .subdev_name = DM365_VPBE_VENC_SUBDEV_NAME, 548 .default_mode = "480p59_94", 549 .num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing), 550 .modes = dm365evm_enc_preset_timing, 551 .if_params = MEDIA_BUS_FMT_FIXED, 552 }, 553 }; 554 555 /* 556 * Amplifiers on the board 557 */ 558 static struct ths7303_platform_data ths7303_pdata = { 559 .ch_1 = 3, 560 .ch_2 = 3, 561 .ch_3 = 3, 562 }; 563 564 static struct amp_config_info vpbe_amp = { 565 .module_name = "ths7303", 566 .is_i2c = 1, 567 .board_info = { 568 I2C_BOARD_INFO("ths7303", 0x2c), 569 .platform_data = &ths7303_pdata, 570 } 571 }; 572 573 static struct vpbe_config dm365evm_display_cfg = { 574 .module_name = "dm365-vpbe-display", 575 .i2c_adapter_id = 1, 576 .amp = &vpbe_amp, 577 .osd = { 578 .module_name = DM365_VPBE_OSD_SUBDEV_NAME, 579 }, 580 .venc = { 581 .module_name = DM365_VPBE_VENC_SUBDEV_NAME, 582 }, 583 .num_outputs = ARRAY_SIZE(dm365evm_vpbe_outputs), 584 .outputs = dm365evm_vpbe_outputs, 585 }; 586 587 static void __init evm_init_i2c(void) 588 { 589 davinci_init_i2c(&i2c_pdata); 590 i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); 591 } 592 593 static inline int have_leds(void) 594 { 595 #ifdef CONFIG_LEDS_CLASS 596 return 1; 597 #else 598 return 0; 599 #endif 600 } 601 602 struct cpld_led { 603 struct led_classdev cdev; 604 u8 mask; 605 }; 606 607 static const struct { 608 const char *name; 609 const char *trigger; 610 } cpld_leds[] = { 611 { "dm365evm::ds2", }, 612 { "dm365evm::ds3", }, 613 { "dm365evm::ds4", }, 614 { "dm365evm::ds5", }, 615 { "dm365evm::ds6", "nand-disk", }, 616 { "dm365evm::ds7", "mmc1", }, 617 { "dm365evm::ds8", "mmc0", }, 618 { "dm365evm::ds9", "heartbeat", }, 619 }; 620 621 static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b) 622 { 623 struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); 624 u8 reg = __raw_readb(cpld + CPLD_LEDS); 625 626 if (b != LED_OFF) 627 reg &= ~led->mask; 628 else 629 reg |= led->mask; 630 __raw_writeb(reg, cpld + CPLD_LEDS); 631 } 632 633 static enum led_brightness cpld_led_get(struct led_classdev *cdev) 634 { 635 struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); 636 u8 reg = __raw_readb(cpld + CPLD_LEDS); 637 638 return (reg & led->mask) ? LED_OFF : LED_FULL; 639 } 640 641 static int __init cpld_leds_init(void) 642 { 643 int i; 644 645 if (!have_leds() || !cpld) 646 return 0; 647 648 /* setup LEDs */ 649 __raw_writeb(0xff, cpld + CPLD_LEDS); 650 for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) { 651 struct cpld_led *led; 652 653 led = kzalloc(sizeof(*led), GFP_KERNEL); 654 if (!led) 655 break; 656 657 led->cdev.name = cpld_leds[i].name; 658 led->cdev.brightness_set = cpld_led_set; 659 led->cdev.brightness_get = cpld_led_get; 660 led->cdev.default_trigger = cpld_leds[i].trigger; 661 led->mask = BIT(i); 662 663 if (led_classdev_register(NULL, &led->cdev) < 0) { 664 kfree(led); 665 break; 666 } 667 } 668 669 return 0; 670 } 671 /* run after subsys_initcall() for LEDs */ 672 fs_initcall(cpld_leds_init); 673 674 675 static void __init evm_init_cpld(void) 676 { 677 u8 mux, resets; 678 const char *label; 679 struct clk *aemif_clk; 680 int rc; 681 682 /* Make sure we can configure the CPLD through CS1. Then 683 * leave it on for later access to MMC and LED registers. 684 */ 685 aemif_clk = clk_get(NULL, "aemif"); 686 if (IS_ERR(aemif_clk)) 687 return; 688 clk_prepare_enable(aemif_clk); 689 690 if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE, 691 "cpld") == NULL) 692 goto fail; 693 cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE); 694 if (!cpld) { 695 release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, 696 SECTION_SIZE); 697 fail: 698 pr_err("ERROR: can't map CPLD\n"); 699 clk_disable_unprepare(aemif_clk); 700 return; 701 } 702 703 /* External muxing for some signals */ 704 mux = 0; 705 706 /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read). 707 * NOTE: SW4 bus width setting must match! 708 */ 709 if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) { 710 /* external keypad mux */ 711 mux |= BIT(7); 712 713 rc = platform_device_register(&davinci_aemif_device); 714 if (rc) 715 pr_warn("%s(): error registering the aemif device: %d\n", 716 __func__, rc); 717 } else { 718 /* no OneNAND support yet */ 719 } 720 721 /* Leave external chips in reset when unused. */ 722 resets = BIT(3) | BIT(2) | BIT(1) | BIT(0); 723 724 /* Static video input config with SN74CBT16214 1-of-3 mux: 725 * - port b1 == tvp7002 (mux lowbits == 1 or 6) 726 * - port b2 == imager (mux lowbits == 2 or 7) 727 * - port b3 == tvp5146 (mux lowbits == 5) 728 * 729 * Runtime switching could work too, with limitations. 730 */ 731 if (have_imager()) { 732 label = "HD imager"; 733 mux |= 2; 734 735 /* externally mux MMC1/ENET/AIC33 to imager */ 736 mux |= BIT(6) | BIT(5) | BIT(3); 737 } else { 738 struct davinci_soc_info *soc_info = &davinci_soc_info; 739 740 /* we can use MMC1 ... */ 741 dm365evm_mmc_configure(); 742 davinci_setup_mmc(1, &dm365evm_mmc_config); 743 744 /* ... and ENET ... */ 745 dm365evm_emac_configure(); 746 soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID; 747 resets &= ~BIT(3); 748 749 /* ... and AIC33 */ 750 resets &= ~BIT(1); 751 752 if (have_tvp7002()) { 753 mux |= 1; 754 resets &= ~BIT(2); 755 label = "tvp7002 HD"; 756 } else { 757 /* default to tvp5146 */ 758 mux |= 5; 759 resets &= ~BIT(0); 760 label = "tvp5146 SD"; 761 } 762 } 763 __raw_writeb(mux, cpld + CPLD_MUX); 764 __raw_writeb(resets, cpld + CPLD_RESETS); 765 pr_info("EVM: %s video input\n", label); 766 767 /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */ 768 } 769 770 static void __init dm365_evm_map_io(void) 771 { 772 dm365_init(); 773 } 774 775 static struct spi_eeprom at25640 = { 776 .byte_len = SZ_64K / 8, 777 .name = "at25640", 778 .page_size = 32, 779 .flags = EE_ADDR2, 780 }; 781 782 static const struct spi_board_info dm365_evm_spi_info[] __initconst = { 783 { 784 .modalias = "at25", 785 .platform_data = &at25640, 786 .max_speed_hz = 10 * 1000 * 1000, 787 .bus_num = 0, 788 .chip_select = 0, 789 .mode = SPI_MODE_0, 790 }, 791 }; 792 793 static __init void dm365_evm_init(void) 794 { 795 int ret; 796 797 dm365_register_clocks(); 798 799 ret = dm365_gpio_register(); 800 if (ret) 801 pr_warn("%s: GPIO init failed: %d\n", __func__, ret); 802 803 nvmem_add_cell_table(&davinci_nvmem_cell_table); 804 nvmem_add_cell_lookups(&davinci_nvmem_cell_lookup, 1); 805 806 evm_init_i2c(); 807 davinci_serial_init(dm365_serial_device); 808 809 dm365evm_emac_configure(); 810 dm365evm_mmc_configure(); 811 812 davinci_setup_mmc(0, &dm365evm_mmc_config); 813 814 dm365_init_video(&vpfe_cfg, &dm365evm_display_cfg); 815 816 /* maybe setup mmc1/etc ... _after_ mmc0 */ 817 evm_init_cpld(); 818 819 #ifdef CONFIG_SND_SOC_DM365_AIC3X_CODEC 820 dm365_init_asp(); 821 #elif defined(CONFIG_SND_SOC_DM365_VOICE_CODEC) 822 dm365_init_vc(); 823 #endif 824 dm365_init_rtc(); 825 dm365_init_ks(&dm365evm_ks_data); 826 827 dm365_init_spi0(BIT(0), dm365_evm_spi_info, 828 ARRAY_SIZE(dm365_evm_spi_info)); 829 } 830 831 MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") 832 .atag_offset = 0x100, 833 .map_io = dm365_evm_map_io, 834 .init_irq = dm365_init_irq, 835 .init_time = dm365_init_time, 836 .init_machine = dm365_evm_init, 837 .init_late = davinci_init_late, 838 .dma_zone_size = SZ_128M, 839 MACHINE_END 840 841
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.