1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 * 02110-1301, USA. 16 */ 17 18#include <linux/module.h> 19#include <linux/kernel.h> 20#include <linux/sched.h> 21#include <linux/time.h> 22#include <linux/init.h> 23#include <linux/interrupt.h> 24#include <linux/spinlock.h> 25#include <linux/delay.h> 26#include <mach/hardware.h> 27#include <linux/io.h> 28 29#include <asm/system.h> 30#include <asm/mach-types.h> 31#include <linux/semaphore.h> 32#include <linux/uaccess.h> 33#include <linux/clk.h> 34 35#include "msm_fb.h" 36#include "tvenc.h" 37 38#define NTSC_TV_DIMENSION_WIDTH 720 39#define NTSC_TV_DIMENSION_HEIGHT 480 40 41static int ntsc_off(struct platform_device *pdev); 42static int ntsc_on(struct platform_device *pdev); 43 44static int ntsc_on(struct platform_device *pdev) 45{ 46 uint32 reg = 0; 47 int ret = 0; 48 struct msm_fb_data_type *mfd; 49 50 mfd = platform_get_drvdata(pdev); 51 52 if (!mfd) 53 return -ENODEV; 54 55 if (mfd->key != MFD_KEY) 56 return -EINVAL; 57 58 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ 59 60 if (mfd->panel.id == NTSC_M) { 61 /* Cr gain 11, Cb gain C6, y_gain 97 */ 62 TV_OUT(TV_GAIN, 0x0081B697); 63 } else { 64 /* Cr gain 11, Cb gain C6, y_gain 97 */ 65 TV_OUT(TV_GAIN, 0x008bc4a3); 66 reg |= TVENC_CTL_NTSCJ_MODE; 67 } 68 69 TV_OUT(TV_CGMS, 0x0); 70 /* NTSC Timing */ 71 TV_OUT(TV_SYNC_1, 0x0020009e); 72 TV_OUT(TV_SYNC_2, 0x011306B4); 73 TV_OUT(TV_SYNC_3, 0x0006000C); 74 TV_OUT(TV_SYNC_4, 0x0028020D); 75 TV_OUT(TV_SYNC_5, 0x005E02FB); 76 TV_OUT(TV_SYNC_6, 0x0006000C); 77 TV_OUT(TV_SYNC_7, 0x00000012); 78 TV_OUT(TV_BURST_V1, 0x0013020D); 79 TV_OUT(TV_BURST_V2, 0x0014020C); 80 TV_OUT(TV_BURST_V3, 0x0013020D); 81 TV_OUT(TV_BURST_V4, 0x0014020C); 82 TV_OUT(TV_BURST_H, 0x00AE00F2); 83 TV_OUT(TV_SOL_REQ_ODD, 0x00280208); 84 TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); 85 86 reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60; 87 88 reg |= TVENC_CTL_Y_FILTER_EN | 89 TVENC_CTL_CR_FILTER_EN | 90 TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; 91#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO 92 reg |= TVENC_CTL_S_VIDEO_EN; 93#endif 94 95 TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ 96 TV_OUT(TV_OFFSET, 0x008080f0); 97 98#ifdef CONFIG_FB_MSM_MDP31 99 TV_OUT(TV_DAC_INTF, 0x29); 100#endif 101 TV_OUT(TV_ENC_CTL, reg); 102 103 reg |= TVENC_CTL_ENC_EN; 104 TV_OUT(TV_ENC_CTL, reg); 105 106 return ret; 107} 108 109static int ntsc_off(struct platform_device *pdev) 110{ 111 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ 112 return 0; 113} 114 115static int __init ntsc_probe(struct platform_device *pdev) 116{ 117 msm_fb_add_device(pdev); 118 119 return 0; 120} 121 122static struct platform_driver this_driver = { 123 .probe = ntsc_probe, 124 .driver = { 125 .name = "tv_ntsc", 126 }, 127}; 128 129static struct msm_fb_panel_data ntsc_panel_data = { 130 .panel_info.xres = NTSC_TV_DIMENSION_WIDTH, 131 .panel_info.yres = NTSC_TV_DIMENSION_HEIGHT, 132 .panel_info.type = TV_PANEL, 133 .panel_info.pdest = DISPLAY_1, 134 .panel_info.wait_cycle = 0, 135 .panel_info.bpp = 16, 136 .panel_info.fb_num = 2, 137 .on = ntsc_on, 138 .off = ntsc_off, 139}; 140 141static struct platform_device this_device = { 142 .name = "tv_ntsc", 143 .id = 0, 144 .dev = { 145 .platform_data = &ntsc_panel_data, 146 } 147}; 148 149static int __init ntsc_init(void) 150{ 151 int ret; 152 153 ret = platform_driver_register(&this_driver); 154 if (!ret) { 155 ret = platform_device_register(&this_device); 156 if (ret) 157 platform_driver_unregister(&this_driver); 158 } 159 160 return ret; 161} 162 163module_init(ntsc_init); 164