Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 55fa6091d83160ca772fc37cebae45d42695a708 296 lines 6.3 kB view raw
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#include <linux/platform_device.h> 35#include <linux/pm_qos_params.h> 36 37#define TVENC_C 38#include "tvenc.h" 39#include "msm_fb.h" 40 41static int tvenc_probe(struct platform_device *pdev); 42static int tvenc_remove(struct platform_device *pdev); 43 44static int tvenc_off(struct platform_device *pdev); 45static int tvenc_on(struct platform_device *pdev); 46 47static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; 48static int pdev_list_cnt; 49 50static struct clk *tvenc_clk; 51static struct clk *tvdac_clk; 52 53static struct platform_driver tvenc_driver = { 54 .probe = tvenc_probe, 55 .remove = tvenc_remove, 56 .suspend = NULL, 57// .suspend_late = NULL, 58// .resume_early = NULL, 59 .resume = NULL, 60 .shutdown = NULL, 61 .driver = { 62 .name = "tvenc", 63 }, 64}; 65 66static struct tvenc_platform_data *tvenc_pdata; 67 68static int tvenc_off(struct platform_device *pdev) 69{ 70 int ret = 0; 71 72 ret = panel_next_off(pdev); 73 74 clk_disable(tvenc_clk); 75 clk_disable(tvdac_clk); 76 77 if (tvenc_pdata && tvenc_pdata->pm_vid_en) 78 ret = tvenc_pdata->pm_vid_en(0); 79 80 //pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", 81 // PM_QOS_DEFAULT_VALUE); 82 83 if (ret) 84 printk(KERN_ERR "%s: pm_vid_en(off) failed! %d\n", 85 __func__, ret); 86 87 return ret; 88} 89 90static int tvenc_on(struct platform_device *pdev) 91{ 92 int ret = 0; 93 94// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", 95// 128000); 96 if (tvenc_pdata && tvenc_pdata->pm_vid_en) 97 ret = tvenc_pdata->pm_vid_en(1); 98 99 if (ret) { 100 printk(KERN_ERR "%s: pm_vid_en(on) failed! %d\n", 101 __func__, ret); 102 return ret; 103 } 104 105 clk_enable(tvenc_clk); 106 clk_enable(tvdac_clk); 107 108 ret = panel_next_on(pdev); 109 110 return ret; 111} 112 113void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd) 114{ 115 uint32 reg = 0, i; 116 117 reg = readl(MSM_TV_ENC_CTL); 118 reg |= TVENC_CTL_TEST_PATT_EN; 119 120 for (i = 0; i < 3; i++) { 121 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ 122 123 switch (i) { 124 /* 125 * TV Encoder - Color Bar Test Pattern 126 */ 127 case 0: 128 reg |= TVENC_CTL_TPG_CLRBAR; 129 break; 130 /* 131 * TV Encoder - Red Frame Test Pattern 132 */ 133 case 1: 134 reg |= TVENC_CTL_TPG_REDCLR; 135 break; 136 /* 137 * TV Encoder - Modulated Ramp Test Pattern 138 */ 139 default: 140 reg |= TVENC_CTL_TPG_MODRAMP; 141 break; 142 } 143 144 TV_OUT(TV_ENC_CTL, reg); 145 mdelay(5000); 146 147 switch (i) { 148 /* 149 * TV Encoder - Color Bar Test Pattern 150 */ 151 case 0: 152 reg &= ~TVENC_CTL_TPG_CLRBAR; 153 break; 154 /* 155 * TV Encoder - Red Frame Test Pattern 156 */ 157 case 1: 158 reg &= ~TVENC_CTL_TPG_REDCLR; 159 break; 160 /* 161 * TV Encoder - Modulated Ramp Test Pattern 162 */ 163 default: 164 reg &= ~TVENC_CTL_TPG_MODRAMP; 165 break; 166 } 167 } 168} 169 170static int tvenc_resource_initialized; 171 172static int tvenc_probe(struct platform_device *pdev) 173{ 174 struct msm_fb_data_type *mfd; 175 struct platform_device *mdp_dev = NULL; 176 struct msm_fb_panel_data *pdata = NULL; 177 int rc; 178 179 if (pdev->id == 0) { 180 tvenc_base = ioremap(pdev->resource[0].start, 181 pdev->resource[0].end - 182 pdev->resource[0].start + 1); 183 if (!tvenc_base) { 184 printk(KERN_ERR 185 "tvenc_base ioremap failed!\n"); 186 return -ENOMEM; 187 } 188 tvenc_pdata = pdev->dev.platform_data; 189 tvenc_resource_initialized = 1; 190 return 0; 191 } 192 193 if (!tvenc_resource_initialized) 194 return -EPERM; 195 196 mfd = platform_get_drvdata(pdev); 197 198 if (!mfd) 199 return -ENODEV; 200 201 if (mfd->key != MFD_KEY) 202 return -EINVAL; 203 204 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) 205 return -ENOMEM; 206 207 if (tvenc_base == NULL) 208 return -ENOMEM; 209 210 mdp_dev = platform_device_alloc("mdp", pdev->id); 211 if (!mdp_dev) 212 return -ENOMEM; 213 214 /* 215 * link to the latest pdev 216 */ 217 mfd->pdev = mdp_dev; 218 mfd->dest = DISPLAY_TV; 219 220 /* 221 * alloc panel device data 222 */ 223 if (platform_device_add_data 224 (mdp_dev, pdev->dev.platform_data, 225 sizeof(struct msm_fb_panel_data))) { 226 printk(KERN_ERR "tvenc_probe: platform_device_add_data failed!\n"); 227 platform_device_put(mdp_dev); 228 return -ENOMEM; 229 } 230 /* 231 * data chain 232 */ 233 pdata = mdp_dev->dev.platform_data; 234 pdata->on = tvenc_on; 235 pdata->off = tvenc_off; 236 pdata->next = pdev; 237 238 /* 239 * get/set panel specific fb info 240 */ 241 mfd->panel_info = pdata->panel_info; 242 mfd->fb_imgType = MDP_YCRYCB_H2V1; 243 244 /* 245 * set driver data 246 */ 247 platform_set_drvdata(mdp_dev, mfd); 248 249 /* 250 * register in mdp driver 251 */ 252 rc = platform_device_add(mdp_dev); 253 if (rc) 254 goto tvenc_probe_err; 255 256 pdev_list[pdev_list_cnt++] = pdev; 257 return 0; 258 259tvenc_probe_err: 260 platform_device_put(mdp_dev); 261 return rc; 262} 263 264static int tvenc_remove(struct platform_device *pdev) 265{ 266// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc"); 267 return 0; 268} 269 270static int tvenc_register_driver(void) 271{ 272 return platform_driver_register(&tvenc_driver); 273} 274 275static int __init tvenc_driver_init(void) 276{ 277 tvenc_clk = clk_get(NULL, "tv_enc_clk"); 278 tvdac_clk = clk_get(NULL, "tv_dac_clk"); 279 280 if (IS_ERR(tvenc_clk)) { 281 printk(KERN_ERR "error: can't get tvenc_clk!\n"); 282 return PTR_ERR(tvenc_clk); 283 } 284 285 if (IS_ERR(tvdac_clk)) { 286 printk(KERN_ERR "error: can't get tvdac_clk!\n"); 287 clk_put(tvenc_clk); 288 return PTR_ERR(tvdac_clk); 289 } 290 291// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", 292// PM_QOS_DEFAULT_VALUE); 293 return tvenc_register_driver(); 294} 295 296module_init(tvenc_driver_init);