-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PATCH] fbdev: Add generic ddc read functionality
Adds functionality to read the EDID information over the DDC bus in a generic way. This code is based on the DDC implementation in the radeon driver. [adaplas] - separate from fbmon.c and place in new file fb_ddc.c - remove dependency to CONFIG_I2C and CONFIG_I2C_ALGOBIT, otherwise, feature will not compile if i2c support is compiled as a module - feature is selectable only by drivers needing it. It must have a 'select FB_DDC if xxx' in Kconfig - change printk's to dev_*, the i2c people prefers it Signed-off-by: Dennis Munsie <dmunsie@cecropia.com> Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
- Loading branch information
Dennis Munsie
authored and
Linus Torvalds
committed
Oct 3, 2006
1 parent
66cf751
commit fc5891c
Showing
4 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* driver/vide/fb_ddc.c - DDC/EDID read support. | ||
* | ||
* Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file COPYING in the main directory of this archive | ||
* for more details. | ||
*/ | ||
|
||
#include <linux/delay.h> | ||
#include <linux/device.h> | ||
#include <linux/fb.h> | ||
#include <linux/i2c-algo-bit.h> | ||
|
||
#include "edid.h" | ||
|
||
#define DDC_ADDR 0x50 | ||
|
||
static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) | ||
{ | ||
unsigned char start = 0x0; | ||
struct i2c_msg msgs[] = { | ||
{ | ||
.addr = DDC_ADDR, | ||
.len = 1, | ||
.buf = &start, | ||
}, { | ||
.addr = DDC_ADDR, | ||
.flags = I2C_M_RD, | ||
.len = EDID_LENGTH, | ||
} | ||
}; | ||
unsigned char *buf; | ||
|
||
buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
if (!buf) { | ||
dev_warn(&adapter->dev, "unable to allocate memory for EDID " | ||
"block.\n"); | ||
return NULL; | ||
} | ||
msgs[1].buf = buf; | ||
|
||
if (i2c_transfer(adapter, msgs, 2) == 2) | ||
return buf; | ||
|
||
dev_warn(&adapter->dev, "unable to read EDID block.\n"); | ||
kfree(buf); | ||
return NULL; | ||
} | ||
|
||
unsigned char *fb_ddc_read(struct i2c_adapter *adapter) | ||
{ | ||
struct i2c_algo_bit_data *algo_data = adapter->algo_data; | ||
unsigned char *edid = NULL; | ||
int i, j; | ||
|
||
algo_data->setscl(algo_data->data, 1); | ||
algo_data->setscl(algo_data->data, 0); | ||
|
||
for (i = 0; i < 3; i++) { | ||
/* For some old monitors we need the | ||
* following process to initialize/stop DDC | ||
*/ | ||
algo_data->setsda(algo_data->data, 0); | ||
msleep(13); | ||
|
||
algo_data->setscl(algo_data->data, 1); | ||
for (j = 0; j < 5; j++) { | ||
msleep(10); | ||
if (algo_data->getscl(algo_data->data)) | ||
break; | ||
} | ||
if (j == 5) | ||
continue; | ||
|
||
algo_data->setsda(algo_data->data, 0); | ||
msleep(15); | ||
algo_data->setscl(algo_data->data, 0); | ||
msleep(15); | ||
algo_data->setsda(algo_data->data, 1); | ||
msleep(15); | ||
|
||
/* Do the real work */ | ||
edid = fb_do_probe_ddc_edid(adapter); | ||
algo_data->setsda(algo_data->data, 0); | ||
algo_data->setscl(algo_data->data, 0); | ||
msleep(15); | ||
|
||
algo_data->setscl(algo_data->data, 1); | ||
for (j = 0; j < 10; j++) { | ||
msleep(10); | ||
if (algo_data->getscl(algo_data->data)) | ||
break; | ||
} | ||
|
||
algo_data->setsda(algo_data->data, 1); | ||
msleep(15); | ||
algo_data->setscl(algo_data->data, 0); | ||
if (edid) | ||
break; | ||
} | ||
/* Release the DDC lines when done or the Apple Cinema HD display | ||
* will switch off | ||
*/ | ||
algo_data->setsda(algo_data->data, 0); | ||
algo_data->setscl(algo_data->data, 0); | ||
|
||
return edid; | ||
} | ||
|
||
EXPORT_SYMBOL_GPL(fb_ddc_read); | ||
|
||
MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>"); | ||
MODULE_DESCRIPTION("DDC/EDID reading support"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters