~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-davinci/board-dm646x-evm.c

Version: ~ [ linux-5.1-rc5 ] ~ [ linux-5.0.7 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.34 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.111 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.168 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.178 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.138 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.65 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * TI DaVinci DM646X EVM board
  3  *
  4  * Derived from: arch/arm/mach-davinci/board-evm.c
  5  * Copyright (C) 2006 Texas Instruments.
  6  *
  7  * (C) 2007-2008, MontaVista Software, Inc.
  8  *
  9  * This file is licensed under the terms of the GNU General Public License
 10  * version 2. This program is licensed "as is" without any warranty of any
 11  * kind, whether express or implied.
 12  *
 13  */
 14 
 15 /**************************************************************************
 16  * Included Files
 17  **************************************************************************/
 18 
 19 #include <linux/kernel.h>
 20 #include <linux/init.h>
 21 #include <linux/leds.h>
 22 #include <linux/gpio.h>
 23 #include <linux/platform_device.h>
 24 #include <linux/i2c.h>
 25 #include <linux/property.h>
 26 #include <linux/platform_data/pcf857x.h>
 27 #include <linux/platform_data/ti-aemif.h>
 28 
 29 #include <media/i2c/tvp514x.h>
 30 #include <media/i2c/adv7343.h>
 31 
 32 #include <linux/mtd/mtd.h>
 33 #include <linux/mtd/rawnand.h>
 34 #include <linux/mtd/partitions.h>
 35 #include <linux/nvmem-provider.h>
 36 #include <linux/clk.h>
 37 #include <linux/export.h>
 38 #include <linux/platform_data/gpio-davinci.h>
 39 #include <linux/platform_data/i2c-davinci.h>
 40 #include <linux/platform_data/mtd-davinci.h>
 41 #include <linux/platform_data/mtd-davinci-aemif.h>
 42 
 43 #include <asm/mach-types.h>
 44 #include <asm/mach/arch.h>
 45 
 46 #include <mach/common.h>
 47 #include <mach/serial.h>
 48 
 49 #include "davinci.h"
 50 #include "irqs.h"
 51 
 52 #define NAND_BLOCK_SIZE         SZ_128K
 53 
 54 /* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
 55  * and U-Boot environment this avoids dependency on any particular combination
 56  * of UBL, U-Boot or flashing tools etc.
 57  */
 58 static struct mtd_partition davinci_nand_partitions[] = {
 59         {
 60                 /* UBL, U-Boot with environment */
 61                 .name           = "bootloader",
 62                 .offset         = MTDPART_OFS_APPEND,
 63                 .size           = 16 * NAND_BLOCK_SIZE,
 64                 .mask_flags     = MTD_WRITEABLE,        /* force read-only */
 65         }, {
 66                 .name           = "kernel",
 67                 .offset         = MTDPART_OFS_APPEND,
 68                 .size           = SZ_4M,
 69                 .mask_flags     = 0,
 70         }, {
 71                 .name           = "filesystem",
 72                 .offset         = MTDPART_OFS_APPEND,
 73                 .size           = MTDPART_SIZ_FULL,
 74                 .mask_flags     = 0,
 75         }
 76 };
 77 
 78 static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
 79         .wsetup         = 29,
 80         .wstrobe        = 24,
 81         .whold          = 14,
 82         .rsetup         = 19,
 83         .rstrobe        = 33,
 84         .rhold          = 0,
 85         .ta             = 29,
 86 };
 87 
 88 static struct davinci_nand_pdata davinci_nand_data = {
 89         .core_chipsel           = 0,
 90         .mask_cle               = 0x80000,
 91         .mask_ale               = 0x40000,
 92         .parts                  = davinci_nand_partitions,
 93         .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
 94         .ecc_mode               = NAND_ECC_HW,
 95         .ecc_bits               = 1,
 96         .options                = 0,
 97 };
 98 
 99 static struct resource davinci_nand_resources[] = {
100         {
101                 .start          = DM646X_ASYNC_EMIF_CS2_SPACE_BASE,
102                 .end            = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1,
103                 .flags          = IORESOURCE_MEM,
104         }, {
105                 .start          = DM646X_ASYNC_EMIF_CONTROL_BASE,
106                 .end            = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
107                 .flags          = IORESOURCE_MEM,
108         },
109 };
110 
111 static struct platform_device davinci_aemif_devices[] = {
112         {
113                 .name           = "davinci_nand",
114                 .id             = 0,
115                 .num_resources  = ARRAY_SIZE(davinci_nand_resources),
116                 .resource       = davinci_nand_resources,
117                 .dev            = {
118                         .platform_data  = &davinci_nand_data,
119                 },
120         },
121 };
122 
123 static struct resource davinci_aemif_resources[] = {
124         {
125                 .start  = DM646X_ASYNC_EMIF_CONTROL_BASE,
126                 .end    = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
127                 .flags  = IORESOURCE_MEM,
128         },
129 };
130 
131 static struct aemif_abus_data davinci_aemif_abus_data[] = {
132         {
133                 .cs     = 1,
134         },
135 };
136 
137 static struct aemif_platform_data davinci_aemif_pdata = {
138         .abus_data              = davinci_aemif_abus_data,
139         .num_abus_data          = ARRAY_SIZE(davinci_aemif_abus_data),
140         .sub_devices            = davinci_aemif_devices,
141         .num_sub_devices        = ARRAY_SIZE(davinci_aemif_devices),
142 };
143 
144 static struct platform_device davinci_aemif_device = {
145         .name           = "ti-aemif",
146         .id             = -1,
147         .dev = {
148                 .platform_data  = &davinci_aemif_pdata,
149         },
150         .resource       = davinci_aemif_resources,
151         .num_resources  = ARRAY_SIZE(davinci_aemif_resources),
152 };
153 
154 #define HAS_ATA         (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
155                          IS_ENABLED(CONFIG_PATA_BK3710))
156 
157 #ifdef CONFIG_I2C
158 /* CPLD Register 0 bits to control ATA */
159 #define DM646X_EVM_ATA_RST              BIT(0)
160 #define DM646X_EVM_ATA_PWD              BIT(1)
161 
162 /* CPLD Register 0 Client: used for I/O Control */
163 static int cpld_reg0_probe(struct i2c_client *client,
164                            const struct i2c_device_id *id)
165 {
166         if (HAS_ATA) {
167                 u8 data;
168                 struct i2c_msg msg[2] = {
169                         {
170                                 .addr = client->addr,
171                                 .flags = I2C_M_RD,
172                                 .len = 1,
173                                 .buf = &data,
174                         },
175                         {
176                                 .addr = client->addr,
177                                 .flags = 0,
178                                 .len = 1,
179                                 .buf = &data,
180                         },
181                 };
182 
183                 /* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */
184                 i2c_transfer(client->adapter, msg, 1);
185                 data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD);
186                 i2c_transfer(client->adapter, msg + 1, 1);
187         }
188 
189         return 0;
190 }
191 
192 static const struct i2c_device_id cpld_reg_ids[] = {
193         { "cpld_reg0", 0, },
194         { },
195 };
196 
197 static struct i2c_driver dm6467evm_cpld_driver = {
198         .driver.name    = "cpld_reg0",
199         .id_table       = cpld_reg_ids,
200         .probe          = cpld_reg0_probe,
201 };
202 
203 /* LEDS */
204 
205 static struct gpio_led evm_leds[] = {
206         { .name = "DS1", .active_low = 1, },
207         { .name = "DS2", .active_low = 1, },
208         { .name = "DS3", .active_low = 1, },
209         { .name = "DS4", .active_low = 1, },
210 };
211 
212 static const struct gpio_led_platform_data evm_led_data = {
213         .num_leds = ARRAY_SIZE(evm_leds),
214         .leds     = evm_leds,
215 };
216 
217 static struct platform_device *evm_led_dev;
218 
219 static int evm_led_setup(struct i2c_client *client, int gpio,
220                         unsigned int ngpio, void *c)
221 {
222         struct gpio_led *leds = evm_leds;
223         int status;
224 
225         while (ngpio--) {
226                 leds->gpio = gpio++;
227                 leds++;
228         }
229 
230         evm_led_dev = platform_device_alloc("leds-gpio", 0);
231         platform_device_add_data(evm_led_dev, &evm_led_data,
232                                 sizeof(evm_led_data));
233 
234         evm_led_dev->dev.parent = &client->dev;
235         status = platform_device_add(evm_led_dev);
236         if (status < 0) {
237                 platform_device_put(evm_led_dev);
238                 evm_led_dev = NULL;
239         }
240         return status;
241 }
242 
243 static int evm_led_teardown(struct i2c_client *client, int gpio,
244                                 unsigned ngpio, void *c)
245 {
246         if (evm_led_dev) {
247                 platform_device_unregister(evm_led_dev);
248                 evm_led_dev = NULL;
249         }
250         return 0;
251 }
252 
253 static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL };
254 
255 static int evm_sw_setup(struct i2c_client *client, int gpio,
256                         unsigned ngpio, void *c)
257 {
258         int status;
259         int i;
260         char label[10];
261 
262         for (i = 0; i < 4; ++i) {
263                 snprintf(label, 10, "user_sw%d", i);
264                 status = gpio_request(gpio, label);
265                 if (status)
266                         goto out_free;
267                 evm_sw_gpio[i] = gpio++;
268 
269                 status = gpio_direction_input(evm_sw_gpio[i]);
270                 if (status) {
271                         gpio_free(evm_sw_gpio[i]);
272                         evm_sw_gpio[i] = -EINVAL;
273                         goto out_free;
274                 }
275 
276                 status = gpio_export(evm_sw_gpio[i], 0);
277                 if (status) {
278                         gpio_free(evm_sw_gpio[i]);
279                         evm_sw_gpio[i] = -EINVAL;
280                         goto out_free;
281                 }
282         }
283         return status;
284 out_free:
285         for (i = 0; i < 4; ++i) {
286                 if (evm_sw_gpio[i] != -EINVAL) {
287                         gpio_free(evm_sw_gpio[i]);
288                         evm_sw_gpio[i] = -EINVAL;
289                 }
290         }
291         return status;
292 }
293 
294 static int evm_sw_teardown(struct i2c_client *client, int gpio,
295                         unsigned ngpio, void *c)
296 {
297         int i;
298 
299         for (i = 0; i < 4; ++i) {
300                 if (evm_sw_gpio[i] != -EINVAL) {
301                         gpio_unexport(evm_sw_gpio[i]);
302                         gpio_free(evm_sw_gpio[i]);
303                         evm_sw_gpio[i] = -EINVAL;
304                 }
305         }
306         return 0;
307 }
308 
309 static int evm_pcf_setup(struct i2c_client *client, int gpio,
310                         unsigned int ngpio, void *c)
311 {
312         int status;
313 
314         if (ngpio < 8)
315                 return -EINVAL;
316 
317         status = evm_sw_setup(client, gpio, 4, c);
318         if (status)
319                 return status;
320 
321         return evm_led_setup(client, gpio+4, 4, c);
322 }
323 
324 static int evm_pcf_teardown(struct i2c_client *client, int gpio,
325                         unsigned int ngpio, void *c)
326 {
327         BUG_ON(ngpio < 8);
328 
329         evm_sw_teardown(client, gpio, 4, c);
330         evm_led_teardown(client, gpio+4, 4, c);
331 
332         return 0;
333 }
334 
335 static struct pcf857x_platform_data pcf_data = {
336         .gpio_base      = DAVINCI_N_GPIO+1,
337         .setup          = evm_pcf_setup,
338         .teardown       = evm_pcf_teardown,
339 };
340 
341 /* Most of this EEPROM is unused, but U-Boot uses some data:
342  *  - 0x7f00, 6 bytes Ethernet Address
343  *  - ... newer boards may have more
344  */
345 
346 static struct nvmem_cell_info dm646x_evm_nvmem_cells[] = {
347         {
348                 .name           = "macaddr",
349                 .offset         = 0x7f00,
350                 .bytes          = ETH_ALEN,
351         }
352 };
353 
354 static struct nvmem_cell_table dm646x_evm_nvmem_cell_table = {
355         .nvmem_name     = "1-00500",
356         .cells          = dm646x_evm_nvmem_cells,
357         .ncells         = ARRAY_SIZE(dm646x_evm_nvmem_cells),
358 };
359 
360 static struct nvmem_cell_lookup dm646x_evm_nvmem_cell_lookup = {
361         .nvmem_name     = "1-00500",
362         .cell_name      = "macaddr",
363         .dev_id         = "davinci_emac.1",
364         .con_id         = "mac-address",
365 };
366 
367 static const struct property_entry eeprom_properties[] = {
368         PROPERTY_ENTRY_U32("pagesize", 64),
369         { }
370 };
371 #endif
372 
373 static u8 dm646x_iis_serializer_direction[] = {
374        TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
375 };
376 
377 static u8 dm646x_dit_serializer_direction[] = {
378        TX_MODE,
379 };
380 
381 static struct snd_platform_data dm646x_evm_snd_data[] = {
382         {
383                 .tx_dma_offset  = 0x400,
384                 .rx_dma_offset  = 0x400,
385                 .op_mode        = DAVINCI_MCASP_IIS_MODE,
386                 .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
387                 .tdm_slots      = 2,
388                 .serial_dir     = dm646x_iis_serializer_direction,
389                 .asp_chan_q     = EVENTQ_0,
390         },
391         {
392                 .tx_dma_offset  = 0x400,
393                 .rx_dma_offset  = 0,
394                 .op_mode        = DAVINCI_MCASP_DIT_MODE,
395                 .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
396                 .tdm_slots      = 32,
397                 .serial_dir     = dm646x_dit_serializer_direction,
398                 .asp_chan_q     = EVENTQ_0,
399         },
400 };
401 
402 #ifdef CONFIG_I2C
403 static struct i2c_client *cpld_client;
404 
405 static int cpld_video_probe(struct i2c_client *client,
406                         const struct i2c_device_id *id)
407 {
408         cpld_client = client;
409         return 0;
410 }
411 
412 static int cpld_video_remove(struct i2c_client *client)
413 {
414         cpld_client = NULL;
415         return 0;
416 }
417 
418 static const struct i2c_device_id cpld_video_id[] = {
419         { "cpld_video", 0 },
420         { }
421 };
422 
423 static struct i2c_driver cpld_video_driver = {
424         .driver = {
425                 .name   = "cpld_video",
426         },
427         .probe          = cpld_video_probe,
428         .remove         = cpld_video_remove,
429         .id_table       = cpld_video_id,
430 };
431 
432 static void evm_init_cpld(void)
433 {
434         i2c_add_driver(&cpld_video_driver);
435 }
436 
437 static struct i2c_board_info __initdata i2c_info[] =  {
438         {
439                 I2C_BOARD_INFO("24c256", 0x50),
440                 .properties  = eeprom_properties,
441         },
442         {
443                 I2C_BOARD_INFO("pcf8574a", 0x38),
444                 .platform_data  = &pcf_data,
445         },
446         {
447                 I2C_BOARD_INFO("cpld_reg0", 0x3a),
448         },
449         {
450                 I2C_BOARD_INFO("tlv320aic33", 0x18),
451         },
452         {
453                 I2C_BOARD_INFO("cpld_video", 0x3b),
454         },
455 };
456 
457 static struct davinci_i2c_platform_data i2c_pdata = {
458         .bus_freq       = 100 /* kHz */,
459         .bus_delay      = 0 /* usec */,
460 };
461 
462 #define VCH2CLK_MASK            (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
463 #define VCH2CLK_SYSCLK8         (BIT(9))
464 #define VCH2CLK_AUXCLK          (BIT(9) | BIT(8))
465 #define VCH3CLK_MASK            (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
466 #define VCH3CLK_SYSCLK8         (BIT(13))
467 #define VCH3CLK_AUXCLK          (BIT(14) | BIT(13))
468 
469 #define VIDCH2CLK               (BIT(10))
470 #define VIDCH3CLK               (BIT(11))
471 #define VIDCH1CLK               (BIT(4))
472 #define TVP7002_INPUT           (BIT(4))
473 #define TVP5147_INPUT           (~BIT(4))
474 #define VPIF_INPUT_ONE_CHANNEL  (BIT(5))
475 #define VPIF_INPUT_TWO_CHANNEL  (~BIT(5))
476 #define TVP5147_CH0             "tvp514x-0"
477 #define TVP5147_CH1             "tvp514x-1"
478 
479 /* spin lock for updating above registers */
480 static spinlock_t vpif_reg_lock;
481 
482 static int set_vpif_clock(int mux_mode, int hd)
483 {
484         unsigned long flags;
485         unsigned int value;
486         int val = 0;
487         int err = 0;
488 
489         if (!cpld_client)
490                 return -ENXIO;
491 
492         /* disable the clock */
493         spin_lock_irqsave(&vpif_reg_lock, flags);
494         value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
495         value |= (VIDCH3CLK | VIDCH2CLK);
496         __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
497         spin_unlock_irqrestore(&vpif_reg_lock, flags);
498 
499         val = i2c_smbus_read_byte(cpld_client);
500         if (val < 0)
501                 return val;
502 
503         if (mux_mode == 1)
504                 val &= ~0x40;
505         else
506                 val |= 0x40;
507 
508         err = i2c_smbus_write_byte(cpld_client, val);
509         if (err)
510                 return err;
511 
512         value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
513         value &= ~(VCH2CLK_MASK);
514         value &= ~(VCH3CLK_MASK);
515 
516         if (hd >= 1)
517                 value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
518         else
519                 value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
520 
521         __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
522 
523         spin_lock_irqsave(&vpif_reg_lock, flags);
524         value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
525         /* enable the clock */
526         value &= ~(VIDCH3CLK | VIDCH2CLK);
527         __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
528         spin_unlock_irqrestore(&vpif_reg_lock, flags);
529 
530         return 0;
531 }
532 
533 static struct vpif_subdev_info dm646x_vpif_subdev[] = {
534         {
535                 .name   = "adv7343",
536                 .board_info = {
537                         I2C_BOARD_INFO("adv7343", 0x2a),
538                 },
539         },
540         {
541                 .name   = "ths7303",
542                 .board_info = {
543                         I2C_BOARD_INFO("ths7303", 0x2c),
544                 },
545         },
546 };
547 
548 static const struct vpif_output dm6467_ch0_outputs[] = {
549         {
550                 .output = {
551                         .index = 0,
552                         .name = "Composite",
553                         .type = V4L2_OUTPUT_TYPE_ANALOG,
554                         .capabilities = V4L2_OUT_CAP_STD,
555                         .std = V4L2_STD_ALL,
556                 },
557                 .subdev_name = "adv7343",
558                 .output_route = ADV7343_COMPOSITE_ID,
559         },
560         {
561                 .output = {
562                         .index = 1,
563                         .name = "Component",
564                         .type = V4L2_OUTPUT_TYPE_ANALOG,
565                         .capabilities = V4L2_OUT_CAP_DV_TIMINGS,
566                 },
567                 .subdev_name = "adv7343",
568                 .output_route = ADV7343_COMPONENT_ID,
569         },
570         {
571                 .output = {
572                         .index = 2,
573                         .name = "S-Video",
574                         .type = V4L2_OUTPUT_TYPE_ANALOG,
575                         .capabilities = V4L2_OUT_CAP_STD,
576                         .std = V4L2_STD_ALL,
577                 },
578                 .subdev_name = "adv7343",
579                 .output_route = ADV7343_SVIDEO_ID,
580         },
581 };
582 
583 static struct vpif_display_config dm646x_vpif_display_config = {
584         .set_clock      = set_vpif_clock,
585         .subdevinfo     = dm646x_vpif_subdev,
586         .subdev_count   = ARRAY_SIZE(dm646x_vpif_subdev),
587         .i2c_adapter_id = 1,
588         .chan_config[0] = {
589                 .outputs = dm6467_ch0_outputs,
590                 .output_count = ARRAY_SIZE(dm6467_ch0_outputs),
591         },
592         .card_name      = "DM646x EVM Video Display",
593 };
594 
595 /**
596  * setup_vpif_input_path()
597  * @channel: channel id (0 - CH0, 1 - CH1)
598  * @sub_dev_name: ptr sub device name
599  *
600  * This will set vpif input to capture data from tvp514x or
601  * tvp7002.
602  */
603 static int setup_vpif_input_path(int channel, const char *sub_dev_name)
604 {
605         int err = 0;
606         int val;
607 
608         /* for channel 1, we don't do anything */
609         if (channel != 0)
610                 return 0;
611 
612         if (!cpld_client)
613                 return -ENXIO;
614 
615         val = i2c_smbus_read_byte(cpld_client);
616         if (val < 0)
617                 return val;
618 
619         if (!strcmp(sub_dev_name, TVP5147_CH0) ||
620             !strcmp(sub_dev_name, TVP5147_CH1))
621                 val &= TVP5147_INPUT;
622         else
623                 val |= TVP7002_INPUT;
624 
625         err = i2c_smbus_write_byte(cpld_client, val);
626         if (err)
627                 return err;
628         return 0;
629 }
630 
631 /**
632  * setup_vpif_input_channel_mode()
633  * @mux_mode:  mux mode. 0 - 1 channel or (1) - 2 channel
634  *
635  * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147)
636  */
637 static int setup_vpif_input_channel_mode(int mux_mode)
638 {
639         unsigned long flags;
640         int err = 0;
641         int val;
642         u32 value;
643 
644         if (!cpld_client)
645                 return -ENXIO;
646 
647         val = i2c_smbus_read_byte(cpld_client);
648         if (val < 0)
649                 return val;
650 
651         spin_lock_irqsave(&vpif_reg_lock, flags);
652         value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
653         if (mux_mode) {
654                 val &= VPIF_INPUT_TWO_CHANNEL;
655                 value |= VIDCH1CLK;
656         } else {
657                 val |= VPIF_INPUT_ONE_CHANNEL;
658                 value &= ~VIDCH1CLK;
659         }
660         __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
661         spin_unlock_irqrestore(&vpif_reg_lock, flags);
662 
663         err = i2c_smbus_write_byte(cpld_client, val);
664         if (err)
665                 return err;
666 
667         return 0;
668 }
669 
670 static struct tvp514x_platform_data tvp5146_pdata = {
671         .clk_polarity = 0,
672         .hs_polarity = 1,
673         .vs_polarity = 1
674 };
675 
676 #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
677 
678 static struct vpif_subdev_info vpif_capture_sdev_info[] = {
679         {
680                 .name   = TVP5147_CH0,
681                 .board_info = {
682                         I2C_BOARD_INFO("tvp5146", 0x5d),
683                         .platform_data = &tvp5146_pdata,
684                 },
685         },
686         {
687                 .name   = TVP5147_CH1,
688                 .board_info = {
689                         I2C_BOARD_INFO("tvp5146", 0x5c),
690                         .platform_data = &tvp5146_pdata,
691                 },
692         },
693 };
694 
695 static struct vpif_input dm6467_ch0_inputs[] = {
696         {
697                 .input = {
698                         .index = 0,
699                         .name = "Composite",
700                         .type = V4L2_INPUT_TYPE_CAMERA,
701                         .capabilities = V4L2_IN_CAP_STD,
702                         .std = TVP514X_STD_ALL,
703                 },
704                 .subdev_name = TVP5147_CH0,
705                 .input_route = INPUT_CVBS_VI2B,
706                 .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
707         },
708 };
709 
710 static struct vpif_input dm6467_ch1_inputs[] = {
711        {
712                 .input = {
713                         .index = 0,
714                         .name = "S-Video",
715                         .type = V4L2_INPUT_TYPE_CAMERA,
716                         .capabilities = V4L2_IN_CAP_STD,
717                         .std = TVP514X_STD_ALL,
718                 },
719                 .subdev_name = TVP5147_CH1,
720                 .input_route = INPUT_SVIDEO_VI2C_VI1C,
721                 .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
722         },
723 };
724 
725 static struct vpif_capture_config dm646x_vpif_capture_cfg = {
726         .setup_input_path = setup_vpif_input_path,
727         .setup_input_channel_mode = setup_vpif_input_channel_mode,
728         .subdev_info = vpif_capture_sdev_info,
729         .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info),
730         .i2c_adapter_id = 1,
731         .chan_config[0] = {
732                 .inputs = dm6467_ch0_inputs,
733                 .input_count = ARRAY_SIZE(dm6467_ch0_inputs),
734                 .vpif_if = {
735                         .if_type = VPIF_IF_BT656,
736                         .hd_pol = 1,
737                         .vd_pol = 1,
738                         .fid_pol = 0,
739                 },
740         },
741         .chan_config[1] = {
742                 .inputs = dm6467_ch1_inputs,
743                 .input_count = ARRAY_SIZE(dm6467_ch1_inputs),
744                 .vpif_if = {
745                         .if_type = VPIF_IF_BT656,
746                         .hd_pol = 1,
747                         .vd_pol = 1,
748                         .fid_pol = 0,
749                 },
750         },
751         .card_name = "DM646x EVM Video Capture",
752 };
753 
754 static void __init evm_init_video(void)
755 {
756         spin_lock_init(&vpif_reg_lock);
757 
758         dm646x_setup_vpif(&dm646x_vpif_display_config,
759                           &dm646x_vpif_capture_cfg);
760 }
761 
762 static void __init evm_init_i2c(void)
763 {
764         davinci_init_i2c(&i2c_pdata);
765         i2c_add_driver(&dm6467evm_cpld_driver);
766         i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
767         evm_init_cpld();
768         evm_init_video();
769 }
770 #endif
771 
772 #define DM646X_REF_FREQ                 27000000
773 #define DM646X_AUX_FREQ                 24000000
774 #define DM6467T_EVM_REF_FREQ            33000000
775 
776 static void __init davinci_map_io(void)
777 {
778         dm646x_init();
779 }
780 
781 static void __init dm646x_evm_init_time(void)
782 {
783         dm646x_init_time(DM646X_REF_FREQ, DM646X_AUX_FREQ);
784 }
785 
786 static void __init dm6467t_evm_init_time(void)
787 {
788         dm646x_init_time(DM6467T_EVM_REF_FREQ, DM646X_AUX_FREQ);
789 }
790 
791 #define DM646X_EVM_PHY_ID               "davinci_mdio-0:01"
792 /*
793  * The following EDMA channels/slots are not being used by drivers (for
794  * example: Timer, GPIO, UART events etc) on dm646x, hence they are being
795  * reserved for codecs on the DSP side.
796  */
797 static const s16 dm646x_dma_rsv_chans[][2] = {
798         /* (offset, number) */
799         { 0,  4},
800         {13,  3},
801         {24,  4},
802         {30,  2},
803         {54,  3},
804         {-1, -1}
805 };
806 
807 static const s16 dm646x_dma_rsv_slots[][2] = {
808         /* (offset, number) */
809         { 0,  4},
810         {13,  3},
811         {24,  4},
812         {30,  2},
813         {54,  3},
814         {128, 384},
815         {-1, -1}
816 };
817 
818 static struct edma_rsv_info dm646x_edma_rsv[] = {
819         {
820                 .rsv_chans      = dm646x_dma_rsv_chans,
821                 .rsv_slots      = dm646x_dma_rsv_slots,
822         },
823 };
824 
825 static __init void evm_init(void)
826 {
827         int ret;
828         struct davinci_soc_info *soc_info = &davinci_soc_info;
829 
830         dm646x_register_clocks();
831 
832         ret = dm646x_gpio_register();
833         if (ret)
834                 pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
835 
836 #ifdef CONFIG_I2C
837         nvmem_add_cell_table(&dm646x_evm_nvmem_cell_table);
838         nvmem_add_cell_lookups(&dm646x_evm_nvmem_cell_lookup, 1);
839         evm_init_i2c();
840 #endif
841 
842         davinci_serial_init(dm646x_serial_device);
843         dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
844         dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
845 
846         if (machine_is_davinci_dm6467tevm())
847                 davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
848 
849         if (platform_device_register(&davinci_aemif_device))
850                 pr_warn("%s: Cannot register AEMIF device.\n", __func__);
851 
852         dm646x_init_edma(dm646x_edma_rsv);
853 
854         if (HAS_ATA)
855                 davinci_init_ide();
856 
857         soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
858 }
859 
860 MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
861         .atag_offset  = 0x100,
862         .map_io       = davinci_map_io,
863         .init_irq     = dm646x_init_irq,
864         .init_time      = dm646x_evm_init_time,
865         .init_machine = evm_init,
866         .init_late      = davinci_init_late,
867         .dma_zone_size  = SZ_128M,
868 MACHINE_END
869 
870 MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
871         .atag_offset  = 0x100,
872         .map_io       = davinci_map_io,
873         .init_irq     = dm646x_init_irq,
874         .init_time      = dm6467t_evm_init_time,
875         .init_machine = evm_init,
876         .init_late      = davinci_init_late,
877         .dma_zone_size  = SZ_128M,
878 MACHINE_END
879 
880 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp