2 * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions
4 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <media/cec.h>
25 u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
28 unsigned int loc = cec_get_edid_spa_location(edid, size);
33 return CEC_PHYS_ADDR_INVALID;
34 return (edid[loc] << 8) | edid[loc + 1];
36 EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
38 void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr)
40 unsigned int loc = cec_get_edid_spa_location(edid, size);
46 edid[loc] = phys_addr >> 8;
47 edid[loc + 1] = phys_addr & 0xff;
50 /* update the checksum */
51 for (i = loc; i < loc + 127; i++)
55 EXPORT_SYMBOL_GPL(cec_set_edid_phys_addr);
57 u16 cec_phys_addr_for_input(u16 phys_addr, u8 input)
59 /* Check if input is sane */
60 if (WARN_ON(input == 0 || input > 0xf))
61 return CEC_PHYS_ADDR_INVALID;
66 if ((phys_addr & 0x0fff) == 0)
67 return phys_addr | (input << 8);
69 if ((phys_addr & 0x00ff) == 0)
70 return phys_addr | (input << 4);
72 if ((phys_addr & 0x000f) == 0)
73 return phys_addr | input;
76 * All nibbles are used so no valid physical addresses can be assigned
79 return CEC_PHYS_ADDR_INVALID;
81 EXPORT_SYMBOL_GPL(cec_phys_addr_for_input);
83 int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
91 if (phys_addr == CEC_PHYS_ADDR_INVALID)
93 for (i = 0; i < 16; i += 4)
94 if (phys_addr & (0xf << i))
99 *parent = phys_addr & (0xfff0 << i);
101 *port = (phys_addr >> i) & 0xf;
102 for (i += 4; i < 16; i += 4)
103 if ((phys_addr & (0xf << i)) == 0)
107 EXPORT_SYMBOL_GPL(cec_phys_addr_validate);