|
@@ -458,3 +458,123 @@ static int set_vpif_clock(int mux_mode, int hd)
|
|
|
val |= 0x40;
|
|
|
|
|
|
err = i2c_smbus_write_byte(cpld_client, val);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
|
|
|
+ value &= ~(VCH2CLK_MASK);
|
|
|
+ value &= ~(VCH3CLK_MASK);
|
|
|
+
|
|
|
+ if (hd >= 1)
|
|
|
+ value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
|
|
|
+ else
|
|
|
+ value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
|
|
|
+
|
|
|
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
|
|
|
+
|
|
|
+ spin_lock_irqsave(&vpif_reg_lock, flags);
|
|
|
+ value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
|
|
|
+ /* enable the clock */
|
|
|
+ value &= ~(VIDCH3CLK | VIDCH2CLK);
|
|
|
+ __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
|
|
|
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct vpif_subdev_info dm646x_vpif_subdev[] = {
|
|
|
+ {
|
|
|
+ .name = "adv7343",
|
|
|
+ .board_info = {
|
|
|
+ I2C_BOARD_INFO("adv7343", 0x2a),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .name = "ths7303",
|
|
|
+ .board_info = {
|
|
|
+ I2C_BOARD_INFO("ths7303", 0x2c),
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct vpif_output dm6467_ch0_outputs[] = {
|
|
|
+ {
|
|
|
+ .output = {
|
|
|
+ .index = 0,
|
|
|
+ .name = "Composite",
|
|
|
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
|
|
|
+ .capabilities = V4L2_OUT_CAP_STD,
|
|
|
+ .std = V4L2_STD_ALL,
|
|
|
+ },
|
|
|
+ .subdev_name = "adv7343",
|
|
|
+ .output_route = ADV7343_COMPOSITE_ID,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .output = {
|
|
|
+ .index = 1,
|
|
|
+ .name = "Component",
|
|
|
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
|
|
|
+ .capabilities = V4L2_OUT_CAP_CUSTOM_TIMINGS,
|
|
|
+ },
|
|
|
+ .subdev_name = "adv7343",
|
|
|
+ .output_route = ADV7343_COMPONENT_ID,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .output = {
|
|
|
+ .index = 2,
|
|
|
+ .name = "S-Video",
|
|
|
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
|
|
|
+ .capabilities = V4L2_OUT_CAP_STD,
|
|
|
+ .std = V4L2_STD_ALL,
|
|
|
+ },
|
|
|
+ .subdev_name = "adv7343",
|
|
|
+ .output_route = ADV7343_SVIDEO_ID,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct vpif_display_config dm646x_vpif_display_config = {
|
|
|
+ .set_clock = set_vpif_clock,
|
|
|
+ .subdevinfo = dm646x_vpif_subdev,
|
|
|
+ .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev),
|
|
|
+ .chan_config[0] = {
|
|
|
+ .outputs = dm6467_ch0_outputs,
|
|
|
+ .output_count = ARRAY_SIZE(dm6467_ch0_outputs),
|
|
|
+ },
|
|
|
+ .card_name = "DM646x EVM",
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * setup_vpif_input_path()
|
|
|
+ * @channel: channel id (0 - CH0, 1 - CH1)
|
|
|
+ * @sub_dev_name: ptr sub device name
|
|
|
+ *
|
|
|
+ * This will set vpif input to capture data from tvp514x or
|
|
|
+ * tvp7002.
|
|
|
+ */
|
|
|
+static int setup_vpif_input_path(int channel, const char *sub_dev_name)
|
|
|
+{
|
|
|
+ int err = 0;
|
|
|
+ int val;
|
|
|
+
|
|
|
+ /* for channel 1, we don't do anything */
|
|
|
+ if (channel != 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (!cpld_client)
|
|
|
+ return -ENXIO;
|
|
|
+
|
|
|
+ val = i2c_smbus_read_byte(cpld_client);
|
|
|
+ if (val < 0)
|
|
|
+ return val;
|
|
|
+
|
|
|
+ if (!strcmp(sub_dev_name, TVP5147_CH0) ||
|
|
|
+ !strcmp(sub_dev_name, TVP5147_CH1))
|
|
|
+ val &= TVP5147_INPUT;
|
|
|
+ else
|
|
|
+ val |= TVP7002_INPUT;
|
|
|
+
|
|
|
+ err = i2c_smbus_write_byte(cpld_client, val);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+ return 0;
|
|
|
+}
|