void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd) { uint32 reg = 0, i; reg = readl(MSM_TV_ENC_CTL); reg |= TVENC_CTL_TEST_PATT_EN; for (i = 0; i < 3; i++) { TV_OUT(TV_ENC_CTL, 0); /* */ switch (i) { /* */ case 0: reg |= TVENC_CTL_TPG_CLRBAR; break; /* */ case 1: reg |= TVENC_CTL_TPG_REDCLR; break; /* */ default: reg |= TVENC_CTL_TPG_MODRAMP; break; } TV_OUT(TV_ENC_CTL, reg); mdelay(5000); switch (i) { /* */ case 0: reg &= ~TVENC_CTL_TPG_CLRBAR; break; /* */ case 1: reg &= ~TVENC_CTL_TPG_REDCLR; break; /* */ default: reg &= ~TVENC_CTL_TPG_MODRAMP; break; } } }
void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd) { uint32 reg = 0, i; reg = readl(MSM_TV_ENC_CTL); reg |= TVENC_CTL_TEST_PATT_EN; for (i = 0; i < 3; i++) { TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ switch (i) { /* * TV Encoder - Color Bar Test Pattern */ case 0: reg |= TVENC_CTL_TPG_CLRBAR; break; /* * TV Encoder - Red Frame Test Pattern */ case 1: reg |= TVENC_CTL_TPG_REDCLR; break; /* * TV Encoder - Modulated Ramp Test Pattern */ default: reg |= TVENC_CTL_TPG_MODRAMP; break; } TV_OUT(TV_ENC_CTL, reg); mdelay(5000); switch (i) { /* * TV Encoder - Color Bar Test Pattern */ case 0: reg &= ~TVENC_CTL_TPG_CLRBAR; break; /* * TV Encoder - Red Frame Test Pattern */ case 1: reg &= ~TVENC_CTL_TPG_REDCLR; break; /* * TV Encoder - Modulated Ramp Test Pattern */ default: reg &= ~TVENC_CTL_TPG_MODRAMP; break; } } }
/* Interrupt debounce timer */ static void tvout_msm_hpd_state_timer(unsigned long data) { #ifdef CONFIG_SUSPEND mutex_lock(&tvout_msm_state_mutex); if (tvout_msm_state->pm_suspended) { mutex_unlock(&tvout_msm_state_mutex); DEV_WARN("%s: ignored, pm_suspended\n", __func__); return; } mutex_unlock(&tvout_msm_state_mutex); #endif if (tvenc_pdata->poll) if (!tvout_msm_state || !tvout_msm_state->disp_powered_up) { DEV_DBG("%s: ignored, display powered off\n", __func__); return; } /* TV_INTR_STATUS[0x204] When a TV_ENC interrupt occurs, then reading this register will indicate what caused the interrupt since that each bit indicates the source of the interrupt that had happened. If multiple interrupt sources had happened, then multiple bits of this register will be set Bit 0 : Load present on Video1 Bit 1 : Load present on Video2 Bit 2 : Load removed on Video1 Bit 3 : Load removed on Video2 */ /* Locking interrupt status is not required because last status read after debouncing is used */ if ((tvout_msm_state->hpd_int_status & 0x05) == 0x05) { /* SW-workaround :If the status read after debouncing is 0x05(indicating both load present & load removed- which can't happen in reality), force an update. If status remains 0x05 after retry, it's a cable unplug event */ if (++tvout_msm_state->five_retry < 2) { uint32 reg; DEV_DBG("tvout: Timer: 0x05\n"); TV_OUT(TV_INTR_CLEAR, 0xf); reg = TV_IN(TV_DAC_INTF); TV_OUT(TV_DAC_INTF, reg & ~TVENC_LOAD_DETECT_EN); TV_OUT(TV_INTR_CLEAR, 0xf); reg = TV_IN(TV_DAC_INTF); TV_OUT(TV_DAC_INTF, reg | TVENC_LOAD_DETECT_EN); return; } } tvout_msm_state->five_retry = 0; tvout_check_status(); }
static int tvout_off(struct platform_device *pdev) { TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ disable_irq(tvout_msm_state->irq); tvout_msm_state->disp_powered_up = FALSE; return 0; }
static void tvout_msm_hpd_work(struct work_struct *work) { uint32 reg; #ifdef CONFIG_SUSPEND mutex_lock(&tvout_msm_state_mutex); if (tvout_msm_state->pm_suspended) { mutex_unlock(&tvout_msm_state_mutex); DEV_WARN("%s: ignored, pm_suspended\n", __func__); return; } mutex_unlock(&tvout_msm_state_mutex); #endif /* Enable power lines & clocks */ tvenc_pdata->pm_vid_en(1); tvenc_set_clock(CLOCK_ON); /* Enable encoder to get a stable interrupt */ reg = TV_IN(TV_ENC_CTL); TV_OUT(TV_ENC_CTL, reg | TVENC_CTL_ENC_EN); /* SW- workaround to update status register */ reg = TV_IN(TV_DAC_INTF); TV_OUT(TV_DAC_INTF, reg & ~TVENC_LOAD_DETECT_EN); TV_OUT(TV_INTR_CLEAR, 0xf); reg = TV_IN(TV_DAC_INTF); TV_OUT(TV_DAC_INTF, reg | TVENC_LOAD_DETECT_EN); tvout_msm_state->hpd_int_status = TV_IN(TV_INTR_STATUS); /* Disable TV encoder */ reg = TV_IN(TV_ENC_CTL); TV_OUT(TV_ENC_CTL, reg & ~TVENC_CTL_ENC_EN); /*Disable power lines & clocks */ tvenc_set_clock(CLOCK_OFF); tvenc_pdata->pm_vid_en(0); DEV_DBG("%s: ISR: 0x%02x\n", __func__, tvout_msm_state->hpd_int_status & 0x05); mod_timer(&tvout_msm_state->hpd_work_timer, jiffies + msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE)); tvout_check_status(); }
static void tvout_msm_turn_on(boolean power_on) { uint32 reg_val = 0; reg_val = TV_IN(TV_ENC_CTL); if (power_on) { DEV_DBG("%s: TV Encoder turned on\n", __func__); reg_val |= TVENC_CTL_ENC_EN; } else { DEV_DBG("%s: TV Encoder turned off\n", __func__); reg_val = 0; } /* Enable TV Encoder*/ TV_OUT(TV_ENC_CTL, reg_val); }
int tvenc_off(struct msm_panel_data *panel) { struct tvenc_info *tvenc = panel_to_tv(panel); pr_info("%s\n", __func__); if (atomic_read(&tvenc->ref_count) == 0) return 0; if (atomic_dec_return(&tvenc->ref_count) == 0) { pr_info("%s, do turn_off\n", __func__); TV_OUT(TV_ENC_CTL, 0); clk_disable(tvenc->tvenc_clk); clk_disable(tvenc->tvdac_clk); } return 0; }
/* ISR for TV out cable detect */ static irqreturn_t tvout_msm_isr(int irq, void *dev_id) { tvout_msm_state->hpd_int_status = TV_IN(TV_INTR_STATUS); TV_OUT(TV_INTR_CLEAR, tvout_msm_state->hpd_int_status); TV_OUT_DEBUG("%s: ISR: 0x%02x\n", __func__, tvout_msm_state->hpd_int_status & 0x05); if (!tvout_msm_state || !tvout_msm_state->disp_powered_up) { TV_OUT_DEBUG("%s: ISR ignored, display not yet powered on\n", __func__); return IRQ_HANDLED; } if (tvout_msm_state->hpd_int_status & BIT(0) || tvout_msm_state->hpd_int_status & BIT(2)) { /* Use .75sec to debounce the interrupt */ mod_timer(&tvout_msm_state->hpd_state_timer, jiffies + msecs_to_jiffies(750)); } return IRQ_HANDLED; }
static int ntsc_on(struct platform_device *pdev) { uint32 reg = 0; int ret = 0; struct msm_fb_data_type *mfd; mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ if (mfd->panel.id == NTSC_M) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081B697); } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x008bc4a3); reg |= TVENC_CTL_NTSCJ_MODE; } TV_OUT(TV_CGMS, 0x0); /* NTSC Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306B4); TV_OUT(TV_SYNC_3, 0x0006000C); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005E02FB); TV_OUT(TV_SYNC_6, 0x0006000C); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0013020D); TV_OUT(TV_BURST_V2, 0x0014020C); TV_OUT(TV_BURST_V3, 0x0013020D); TV_OUT(TV_BURST_V4, 0x0014020C); TV_OUT(TV_BURST_H, 0x00AE00F2); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60; reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; #ifdef CONFIG_FB_MSM_TVOUT_SVIDEO reg |= TVENC_CTL_S_VIDEO_EN; #endif TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); #ifdef CONFIG_FB_MSM_MDP31 TV_OUT(TV_DAC_INTF, 0x29); #endif TV_OUT(TV_ENC_CTL, reg); reg |= TVENC_CTL_ENC_EN; TV_OUT(TV_ENC_CTL, reg); return ret; }
static int ntsc_off(struct platform_device *pdev) { TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ return 0; }
static int __devinit tvout_probe(struct platform_device *pdev) { int rc = 0; uint32 reg; struct platform_device *fb_dev; #ifdef CONFIG_FB_MSM_TVOUT_NTSC_M external_common_state->video_resolution = NTSC_M; #elif defined CONFIG_FB_MSM_TVOUT_NTSC_J external_common_state->video_resolution = NTSC_J; #elif defined CONFIG_FB_MSM_TVOUT_PAL_M external_common_state->video_resolution = PAL_M; #elif defined CONFIG_FB_MSM_TVOUT_PAL_N external_common_state->video_resolution = PAL_N; #elif defined CONFIG_FB_MSM_TVOUT_PAL_BDGHIN external_common_state->video_resolution = PAL_BDGHIN; #endif external_common_state->dev = &pdev->dev; if (pdev->id == 0) { struct resource *res; #define GET_RES(name, mode) do { \ res = platform_get_resource_byname(pdev, mode, name); \ if (!res) { \ DEV_DBG("'" name "' resource not found\n"); \ rc = -ENODEV; \ goto error; \ } \ } while (0) #define GET_IRQ(var, name) do { \ GET_RES(name, IORESOURCE_IRQ); \ var = res->start; \ } while (0) GET_IRQ(tvout_msm_state->irq, "tvout_device_irq"); #undef GET_IRQ #undef GET_RES return 0; } DEV_DBG("%s: tvout_msm_state->irq : %d", __func__, tvout_msm_state->irq); rc = request_irq(tvout_msm_state->irq, &tvout_msm_isr, IRQF_TRIGGER_HIGH, "tvout_msm_isr", NULL); if (rc) { DEV_DBG("Init FAILED: IRQ request, rc=%d\n", rc); goto error; } disable_irq(tvout_msm_state->irq); init_timer(&tvout_msm_state->hpd_state_timer); tvout_msm_state->hpd_state_timer.function = tvout_msm_hpd_state_timer; tvout_msm_state->hpd_state_timer.data = (uint32)NULL; tvout_msm_state->hpd_state_timer.expires = jiffies + msecs_to_jiffies(1000); if (tvenc_pdata->poll) { init_timer(&tvout_msm_state->hpd_work_timer); tvout_msm_state->hpd_work_timer.function = tvout_msm_hpd_work_timer; tvout_msm_state->hpd_work_timer.data = (uint32)NULL; tvout_msm_state->hpd_work_timer.expires = jiffies + msecs_to_jiffies(1000); } fb_dev = msm_fb_add_device(pdev); if (fb_dev) { rc = external_common_state_create(fb_dev); if (rc) { DEV_ERR("Init FAILED: tvout_msm_state_create, rc=%d\n", rc); goto error; } if (tvenc_pdata->poll) { /* Start polling timer to detect load */ mod_timer(&tvout_msm_state->hpd_work_timer, jiffies + msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE)); } else { /* Enable interrupt to detect load */ tvenc_set_encoder_clock(CLOCK_ON); reg = TV_IN(TV_DAC_INTF); reg |= TVENC_LOAD_DETECT_EN; TV_OUT(TV_DAC_INTF, reg); TV_OUT(TV_INTR_ENABLE, 0x5); enable_irq(tvout_msm_state->irq); } } else DEV_ERR("Init FAILED: failed to add fb device\n"); error: return 0; }
static int tvout_on(struct platform_device *pdev) { uint32 reg = 0; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #ifdef CONFIG_SUSPEND mutex_lock(&tvout_msm_state_mutex); if (tvout_msm_state->pm_suspended) { mutex_unlock(&tvout_msm_state_mutex); DEV_WARN("%s: ignored, pm_suspended\n", __func__); return -ENODEV; } mutex_unlock(&tvout_msm_state_mutex); #endif var = &mfd->fbi->var; if (var->reserved[3] >= NTSC_M && var->reserved[3] <= PAL_N) external_common_state->video_resolution = var->reserved[3]; tvout_msm_state->pdev = pdev; if (del_timer(&tvout_msm_state->hpd_work_timer)) DEV_DBG("%s: work timer stopped\n", __func__); TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ switch (external_common_state->video_resolution) { case NTSC_M: case NTSC_J: TV_OUT(TV_CGMS, 0x0); /* NTSC Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306B4); TV_OUT(TV_SYNC_3, 0x0006000C); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005E02FB); TV_OUT(TV_SYNC_6, 0x0006000C); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0013020D); TV_OUT(TV_BURST_V2, 0x0014020C); TV_OUT(TV_BURST_V3, 0x0013020D); TV_OUT(TV_BURST_V4, 0x0014020C); TV_OUT(TV_BURST_H, 0x00AE00F2); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60; if (external_common_state->video_resolution == NTSC_M) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081B697); } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x008bc4a3); reg |= TVENC_CTL_NTSCJ_MODE; } var->yres = 480; break; case PAL_BDGHIN: case PAL_N: /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); if (external_common_state->video_resolution == PAL_BDGHIN) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0088c1a0); TV_OUT(TV_CGMS, 0x00012345); TV_OUT(TV_SYNC_2, 0x011f06c0); TV_OUT(TV_BURST_H, 0x00af00ea); reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN; } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_SYNC_2, 0x12006c0); TV_OUT(TV_BURST_H, 0x00af00fa); reg |= TVENC_CTL_TV_MODE_PAL_N; } var->yres = 576; break; case PAL_M: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306b4); TV_OUT(TV_SYNC_3, 0x0006000c); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005e02fb); TV_OUT(TV_SYNC_6, 0x0006000c); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0012020b); TV_OUT(TV_BURST_V2, 0x0016020c); TV_OUT(TV_BURST_V3, 0x00150209); TV_OUT(TV_BURST_V4, 0x0013020c); TV_OUT(TV_BURST_H, 0x00bf010b); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_PAL_M; var->yres = 480; break; default: return -ENODEV; } reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; /* DC offset to 0. */ TV_OUT(TV_LEVEL, 0x00000000); TV_OUT(TV_OFFSET, 0x008080f0); #ifdef CONFIG_FB_MSM_TVOUT_SVIDEO reg |= TVENC_CTL_S_VIDEO_EN; #endif #if defined(CONFIG_FB_MSM_MDP31) TV_OUT(TV_DAC_INTF, 0x29); #endif TV_OUT(TV_ENC_CTL, reg); if (!tvout_msm_state->hpd_initialized) { tvout_msm_state->hpd_initialized = TRUE; /* Load detect enable */ reg = TV_IN(TV_DAC_INTF); reg |= TVENC_LOAD_DETECT_EN; TV_OUT(TV_DAC_INTF, reg); } tvout_msm_state->disp_powered_up = TRUE; tvout_msm_turn_on(TRUE); if (tvenc_pdata->poll) { /* Enable Load present & removal interrupts for Video1 */ TV_OUT(TV_INTR_ENABLE, 0x5); /* Enable interrupts when display is on */ enable_irq(tvout_msm_state->irq); } return 0; }
static int pal_on(struct platform_device *pdev) { uint32 reg = 0; int ret = 0; struct msm_fb_data_type *mfd; mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ switch (mfd->panel.id) { case PAL_BDGHIN: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0088c1a0); TV_OUT(TV_CGMS, 0x00012345); TV_OUT(TV_TEST_MUX, 0x0); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_2, 0x011f06c0); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_BURST_H, 0x00af00ea); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN; break; case PAL_M: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306b4); TV_OUT(TV_SYNC_3, 0x0006000c); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005e02fb); TV_OUT(TV_SYNC_6, 0x0006000c); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0012020b); TV_OUT(TV_BURST_V2, 0x0016020c); TV_OUT(TV_BURST_V3, 0x00150209); TV_OUT(TV_BURST_V4, 0x0013020c); TV_OUT(TV_BURST_H, 0x00bf010b); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_PAL_M; break; case PAL_N: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_2, 0x12006c0); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_BURST_H, 0x00af00fa); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); reg |= TVENC_CTL_TV_MODE_PAL_N; break; default: return -ENODEV; } reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; #ifdef CONFIG_FB_MSM_TVOUT_SVIDEO reg |= TVENC_CTL_S_VIDEO_EN; #endif TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); #ifdef CONFIG_FB_MSM_MDP31 TV_OUT(TV_DAC_INTF, 0x29); #endif TV_OUT(TV_ENC_CTL, reg); reg |= TVENC_CTL_ENC_EN; TV_OUT(TV_ENC_CTL, reg); return ret; }
int tvenc_set_mode(int mode) { uint32_t reg = 0; int ret = 0; TV_OUT(TV_ENC_CTL, 0); switch (mode) { case NTSC_M: case NTSC_J: if (mode == NTSC_M) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081B697); } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x008bc4a3); reg |= TVENC_CTL_NTSCJ_MODE; } TV_OUT(TV_CGMS, 0x0); /* NTSC Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306B4); TV_OUT(TV_SYNC_3, 0x0006000C); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005E02FB); TV_OUT(TV_SYNC_6, 0x0006000C); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0013020D); TV_OUT(TV_BURST_V2, 0x0014020C); TV_OUT(TV_BURST_V3, 0x0013020D); TV_OUT(TV_BURST_V4, 0x0014020C); TV_OUT(TV_BURST_H, 0x00AE00F2); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60 | TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); break; case PAL_BDGHIN: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0088c1a0); TV_OUT(TV_CGMS, 0x00012345); TV_OUT(TV_TEST_MUX, 0x0); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_2, 0x011f06c0); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_BURST_H, 0x00af00ea); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN; reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); break; case PAL_M: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306b4); TV_OUT(TV_SYNC_3, 0x0006000c); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005e02fb); TV_OUT(TV_SYNC_6, 0x0006000c); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0012020b); TV_OUT(TV_BURST_V2, 0x0016020c); TV_OUT(TV_BURST_V3, 0x00150209); TV_OUT(TV_BURST_V4, 0x0013020c); TV_OUT(TV_BURST_H, 0x00bf010b); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_PAL_M; reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); break; case PAL_N: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_2, 0x12006c0); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_BURST_H, 0x00af00fa); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); reg |= TVENC_CTL_TV_MODE_PAL_N; reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ TV_OUT(TV_OFFSET, 0x008080f0); break; default: return -ENODEV; } #ifdef CONFIG_MSM_MDP31 TV_OUT(TV_DAC_INTF, 0x29); #endif TV_OUT(TV_ENC_CTL, reg); reg |= TVENC_CTL_ENC_EN; TV_OUT(TV_ENC_CTL, reg); return ret; }
static int tvout_on(struct platform_device *pdev) { uint32 reg = 0; int ret = 0, rc; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);; if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; var = &mfd->fbi->var; #ifdef CONFIG_HUAWEI_KERNEL if(TVOUT_PAL == var->reserved[4]) { tvout_msm_state->video_mode = PAL_M; } else { tvout_msm_state->video_mode = NTSC_M; } #endif if (!tvout_msm_state->uevent_kobj) { rc = tvout_msm_state_create(pdev); if (rc) { pr_err("Init FAILED: tvout_msm_state_create, rc=%d\n", rc); goto error; } kobject_uevent(tvout_msm_state->uevent_kobj, KOBJ_ADD); pr_info("%s: kobject_uevent(KOBJ_ADD)\n", __func__); } TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ switch (tvout_msm_state->video_mode) { case NTSC_M: case NTSC_J: TV_OUT(TV_CGMS, 0x0); /* NTSC Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306B4); TV_OUT(TV_SYNC_3, 0x0006000C); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005E02FB); TV_OUT(TV_SYNC_6, 0x0006000C); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0013020D); TV_OUT(TV_BURST_V2, 0x0014020C); TV_OUT(TV_BURST_V3, 0x0013020D); TV_OUT(TV_BURST_V4, 0x0014020C); TV_OUT(TV_BURST_H, 0x00AE00F2); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60; if (tvout_msm_state->video_mode == NTSC_M) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081B697); } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x008bc4a3); reg |= TVENC_CTL_NTSCJ_MODE; } var->yres = 480; break; case PAL_BDGHIN: case PAL_N: /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x00180097); TV_OUT(TV_SYNC_3, 0x0005000a); TV_OUT(TV_SYNC_4, 0x00320271); TV_OUT(TV_SYNC_5, 0x005602f9); TV_OUT(TV_SYNC_6, 0x0005000a); TV_OUT(TV_SYNC_7, 0x0000000f); TV_OUT(TV_BURST_V1, 0x0012026e); TV_OUT(TV_BURST_V2, 0x0011026d); TV_OUT(TV_BURST_V3, 0x00100270); TV_OUT(TV_BURST_V4, 0x0013026f); TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); if (tvout_msm_state->video_mode == PAL_BDGHIN) { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0088c1a0); TV_OUT(TV_CGMS, 0x00012345); TV_OUT(TV_SYNC_2, 0x011f06c0); TV_OUT(TV_BURST_H, 0x00af00ea); reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN; } else { /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_SYNC_2, 0x12006c0); TV_OUT(TV_BURST_H, 0x00af00fa); reg |= TVENC_CTL_TV_MODE_PAL_N; } var->yres = 576; break; case PAL_M: /* Cr gain 11, Cb gain C6, y_gain 97 */ TV_OUT(TV_GAIN, 0x0081b697); TV_OUT(TV_CGMS, 0x000af317); TV_OUT(TV_TEST_MUX, 0x000001c3); TV_OUT(TV_TEST_MODE, 0x00000002); /* PAL Timing */ TV_OUT(TV_SYNC_1, 0x0020009e); TV_OUT(TV_SYNC_2, 0x011306b4); TV_OUT(TV_SYNC_3, 0x0006000c); TV_OUT(TV_SYNC_4, 0x0028020D); TV_OUT(TV_SYNC_5, 0x005e02fb); TV_OUT(TV_SYNC_6, 0x0006000c); TV_OUT(TV_SYNC_7, 0x00000012); TV_OUT(TV_BURST_V1, 0x0012020b); TV_OUT(TV_BURST_V2, 0x0016020c); TV_OUT(TV_BURST_V3, 0x00150209); TV_OUT(TV_BURST_V4, 0x0013020c); TV_OUT(TV_BURST_H, 0x00bf010b); TV_OUT(TV_SOL_REQ_ODD, 0x00280208); TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); reg |= TVENC_CTL_TV_MODE_PAL_M; var->yres = 480; break; default: return -ENODEV; } #ifdef CONFIG_FB_MSM_TVOUT_SVIDEO reg |= TVENC_CTL_S_VIDEO_EN; #endif reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN | TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; /* DC offset to 0. */ TV_OUT(TV_LEVEL, 0x00000000); TV_OUT(TV_OFFSET, 0x008080f0); #if defined(CONFIG_FB_MSM_MDP31) TV_OUT(TV_DAC_INTF, 0x29); #endif TV_OUT(TV_ENC_CTL, reg); /* Enable TV Out */ reg |= TVENC_CTL_ENC_EN; TV_OUT(TV_ENC_CTL, reg); reg = TV_IN(TV_DAC_INTF); reg |= TVENC_LOAD_DETECT_EN; TV_OUT(TV_DAC_INTF, reg); /* Enable Load present & removal interrupts for Video1 */ TV_OUT(TV_INTR_ENABLE, 0x5); tvout_msm_state->disp_powered_up = TRUE; /* Enable interrupts when display is on */ enable_irq(tvout_msm_state->irq); error: return ret; }