1 /* A simple I2C slave for returning monitor EDID data via DDC.
3 * Copyright (c) 2011 Linaro Limited
4 * Written by Peter Maydell
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "hw/i2c/i2c.h"
22 #include "hw/i2c/i2c-ddc.h"
25 #define DEBUG_I2CDDC 0
28 #define DPRINTF(fmt, ...) do { \
30 qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
34 /* Structure defining a monitor's characteristics in a
35 * readable format: this should be passed to build_edid_blob()
36 * to convert it into the 128 byte binary EDID blob.
37 * Not all bits of the EDID are customisable here.
40 char manuf_id
[3]; /* three upper case letters */
48 char monitor_name
[14];
49 char serial_no_string
[14];
51 uint8_t vmin
; /* Hz */
52 uint8_t vmax
; /* Hz */
53 uint8_t hmin
; /* kHz */
54 uint8_t hmax
; /* kHz */
55 uint8_t pixclock
; /* MHz / 10 */
56 uint8_t timing_data
[18];
59 typedef struct EDIDData EDIDData
;
61 /* EDID data for a simple LCD monitor */
62 static const EDIDData lcd_edid
= {
63 /* The manuf_id ought really to be an assigned EISA ID */
72 .monitor_name
= "QEMU monitor",
73 .serial_no_string
= "1",
80 /* Borrowed from a 21" LCD */
81 0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40,
82 0xc0, 0x13, 0x00, 0x98, 0x32, 0x11, 0x00, 0x00, 0x1e
86 static uint8_t manuf_char_to_int(char c
)
88 return (c
- 'A') & 0x1f;
91 static void write_ascii_descriptor_block(uint8_t *descblob
, uint8_t blocktype
,
94 /* Write an EDID Descriptor Block of the "ascii string" type */
96 descblob
[0] = descblob
[1] = descblob
[2] = descblob
[4] = 0;
97 descblob
[3] = blocktype
;
98 /* The rest is 13 bytes of ASCII; if less then the rest must
99 * be filled with newline then spaces
101 for (i
= 5; i
< 19; i
++) {
102 descblob
[i
] = string
[i
- 5];
108 descblob
[i
++] = '\n';
110 for ( ; i
< 19; i
++) {
115 static void write_range_limits_descriptor(const EDIDData
*edid
,
119 descblob
[0] = descblob
[1] = descblob
[2] = descblob
[4] = 0;
121 descblob
[5] = edid
->vmin
;
122 descblob
[6] = edid
->vmax
;
123 descblob
[7] = edid
->hmin
;
124 descblob
[8] = edid
->hmax
;
125 descblob
[9] = edid
->pixclock
;
128 for (i
= 12; i
< 19; i
++) {
133 static void build_edid_blob(const EDIDData
*edid
, uint8_t *blob
)
135 /* Write an EDID 1.3 format blob (128 bytes) based
136 * on the EDIDData structure.
142 blob
[0] = blob
[7] = 0;
143 for (i
= 1 ; i
< 7; i
++) {
146 /* 08-09 : manufacturer ID */
147 blob
[8] = (manuf_char_to_int(edid
->manuf_id
[0]) << 2)
148 | (manuf_char_to_int(edid
->manuf_id
[1]) >> 3);
149 blob
[9] = (manuf_char_to_int(edid
->manuf_id
[1]) << 5)
150 | manuf_char_to_int(edid
->manuf_id
[2]);
151 /* 10-11 : product ID code */
152 blob
[10] = edid
->product_id
;
153 blob
[11] = edid
->product_id
>> 8;
154 blob
[12] = edid
->serial_no
;
155 blob
[13] = edid
->serial_no
>> 8;
156 blob
[14] = edid
->serial_no
>> 16;
157 blob
[15] = edid
->serial_no
>> 24;
158 /* 16 : week of manufacture */
159 blob
[16] = edid
->manuf_week
;
160 /* 17 : year of manufacture - 1990 */
161 blob
[17] = edid
->manuf_year
- 1990;
162 /* 18, 19 : EDID version and revision */
165 /* 20 - 24 : basic display parameters */
166 /* We are always a digital display */
168 /* 21, 22 : max h/v size in cm */
169 blob
[21] = edid
->h_cm
;
170 blob
[22] = edid
->v_cm
;
171 /* 23 : gamma (divide by 100 then add 1 for actual value) */
172 blob
[23] = edid
->gamma
;
173 /* 24 feature support: no power management, RGB, preferred timing mode,
174 * standard colour space
177 /* 25 - 34 : chromaticity coordinates. These are the
178 * standard sRGB chromaticity values
190 /* 35, 36 : Established timings: claim to support everything */
191 blob
[35] = blob
[36] = 0xff;
192 /* 37 : manufacturer's reserved timing: none */
194 /* 38 - 53 : standard timing identification
195 * don't claim anything beyond what the 'established timings'
196 * already provide. Unused slots must be (0x1, 0x1)
198 for (i
= 38; i
< 54; i
++) {
201 /* 54 - 71 : descriptor block 1 : must be preferred timing data */
202 memcpy(blob
+ 54, edid
->timing_data
, 18);
203 /* 72 - 89, 90 - 107, 108 - 125 : descriptor block 2, 3, 4
204 * Order not important, but we must have a monitor name and a
205 * range limits descriptor.
207 write_range_limits_descriptor(edid
, blob
+ 72);
208 write_ascii_descriptor_block(blob
+ 90, 0xfc, edid
->monitor_name
);
209 write_ascii_descriptor_block(blob
+ 108, 0xff, edid
->serial_no_string
);
211 /* 126 : extension flag */
215 for (i
= 0; i
< 127; i
++) {
221 qemu_hexdump((char *)blob
, stdout
, "", 128);
225 static void i2c_ddc_reset(DeviceState
*ds
)
227 I2CDDCState
*s
= I2CDDC(ds
);
229 s
->firstbyte
= false;
233 static void i2c_ddc_event(I2CSlave
*i2c
, enum i2c_event event
)
235 I2CDDCState
*s
= I2CDDC(i2c
);
237 if (event
== I2C_START_SEND
) {
242 static int i2c_ddc_rx(I2CSlave
*i2c
)
244 I2CDDCState
*s
= I2CDDC(i2c
);
247 value
= s
->edid_blob
[s
->reg
];
252 static int i2c_ddc_tx(I2CSlave
*i2c
, uint8_t data
)
254 I2CDDCState
*s
= I2CDDC(i2c
);
257 s
->firstbyte
= false;
258 DPRINTF("[EDID] Written new pointer: %u\n", data
);
262 /* Ignore all writes */
267 static void i2c_ddc_init(Object
*obj
)
269 I2CDDCState
*s
= I2CDDC(obj
);
270 build_edid_blob(&lcd_edid
, s
->edid_blob
);
273 static const VMStateDescription vmstate_i2c_ddc
= {
276 .fields
= (VMStateField
[]) {
277 VMSTATE_BOOL(firstbyte
, I2CDDCState
),
278 VMSTATE_UINT8(reg
, I2CDDCState
),
279 VMSTATE_END_OF_LIST()
283 static void i2c_ddc_class_init(ObjectClass
*oc
, void *data
)
285 DeviceClass
*dc
= DEVICE_CLASS(oc
);
286 I2CSlaveClass
*isc
= I2C_SLAVE_CLASS(oc
);
288 dc
->reset
= i2c_ddc_reset
;
289 dc
->vmsd
= &vmstate_i2c_ddc
;
290 isc
->event
= i2c_ddc_event
;
291 isc
->recv
= i2c_ddc_rx
;
292 isc
->send
= i2c_ddc_tx
;
295 static TypeInfo i2c_ddc_info
= {
297 .parent
= TYPE_I2C_SLAVE
,
298 .instance_size
= sizeof(I2CDDCState
),
299 .instance_init
= i2c_ddc_init
,
300 .class_init
= i2c_ddc_class_init
303 static void ddc_register_devices(void)
305 type_register_static(&i2c_ddc_info
);
308 type_init(ddc_register_devices
);