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 v3.0-rc4 118 lines 2.6 kB view raw
1/* 2 * driver/vide/fb_ddc.c - DDC/EDID read support. 3 * 4 * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11#include <linux/delay.h> 12#include <linux/device.h> 13#include <linux/fb.h> 14#include <linux/i2c-algo-bit.h> 15#include <linux/slab.h> 16 17#include "edid.h" 18 19#define DDC_ADDR 0x50 20 21static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) 22{ 23 unsigned char start = 0x0; 24 unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); 25 struct i2c_msg msgs[] = { 26 { 27 .addr = DDC_ADDR, 28 .flags = 0, 29 .len = 1, 30 .buf = &start, 31 }, { 32 .addr = DDC_ADDR, 33 .flags = I2C_M_RD, 34 .len = EDID_LENGTH, 35 .buf = buf, 36 } 37 }; 38 39 if (!buf) { 40 dev_warn(&adapter->dev, "unable to allocate memory for EDID " 41 "block.\n"); 42 return NULL; 43 } 44 45 if (i2c_transfer(adapter, msgs, 2) == 2) 46 return buf; 47 48 dev_warn(&adapter->dev, "unable to read EDID block.\n"); 49 kfree(buf); 50 return NULL; 51} 52 53unsigned char *fb_ddc_read(struct i2c_adapter *adapter) 54{ 55 struct i2c_algo_bit_data *algo_data = adapter->algo_data; 56 unsigned char *edid = NULL; 57 int i, j; 58 59 algo_data->setscl(algo_data->data, 1); 60 61 for (i = 0; i < 3; i++) { 62 /* For some old monitors we need the 63 * following process to initialize/stop DDC 64 */ 65 algo_data->setsda(algo_data->data, 1); 66 msleep(13); 67 68 algo_data->setscl(algo_data->data, 1); 69 for (j = 0; j < 5; j++) { 70 msleep(10); 71 if (algo_data->getscl(algo_data->data)) 72 break; 73 } 74 if (j == 5) 75 continue; 76 77 algo_data->setsda(algo_data->data, 0); 78 msleep(15); 79 algo_data->setscl(algo_data->data, 0); 80 msleep(15); 81 algo_data->setsda(algo_data->data, 1); 82 msleep(15); 83 84 /* Do the real work */ 85 edid = fb_do_probe_ddc_edid(adapter); 86 algo_data->setsda(algo_data->data, 0); 87 algo_data->setscl(algo_data->data, 0); 88 msleep(15); 89 90 algo_data->setscl(algo_data->data, 1); 91 for (j = 0; j < 10; j++) { 92 msleep(10); 93 if (algo_data->getscl(algo_data->data)) 94 break; 95 } 96 97 algo_data->setsda(algo_data->data, 1); 98 msleep(15); 99 algo_data->setscl(algo_data->data, 0); 100 algo_data->setsda(algo_data->data, 0); 101 if (edid) 102 break; 103 } 104 /* Release the DDC lines when done or the Apple Cinema HD display 105 * will switch off 106 */ 107 algo_data->setsda(algo_data->data, 1); 108 algo_data->setscl(algo_data->data, 1); 109 110 adapter->class |= I2C_CLASS_DDC; 111 return edid; 112} 113 114EXPORT_SYMBOL_GPL(fb_ddc_read); 115 116MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>"); 117MODULE_DESCRIPTION("DDC/EDID reading support"); 118MODULE_LICENSE("GPL");