0001
0002
0003
0004
0005
0006
0007 #include <drm/drm_print.h>
0008
0009 #include "logicvc_drm.h"
0010 #include "logicvc_layer.h"
0011 #include "logicvc_of.h"
0012
0013 static struct logicvc_of_property_sv logicvc_of_display_interface_sv[] = {
0014 { "lvds-4bits", LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS },
0015 { "lvds-3bits", LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS },
0016 { },
0017 };
0018
0019 static struct logicvc_of_property_sv logicvc_of_display_colorspace_sv[] = {
0020 { "rgb", LOGICVC_DISPLAY_COLORSPACE_RGB },
0021 { "yuv422", LOGICVC_DISPLAY_COLORSPACE_YUV422 },
0022 { "yuv444", LOGICVC_DISPLAY_COLORSPACE_YUV444 },
0023 { },
0024 };
0025
0026 static struct logicvc_of_property_sv logicvc_of_layer_colorspace_sv[] = {
0027 { "rgb", LOGICVC_LAYER_COLORSPACE_RGB },
0028 { "yuv", LOGICVC_LAYER_COLORSPACE_YUV },
0029 { },
0030 };
0031
0032 static struct logicvc_of_property_sv logicvc_of_layer_alpha_mode_sv[] = {
0033 { "layer", LOGICVC_LAYER_ALPHA_LAYER },
0034 { "pixel", LOGICVC_LAYER_ALPHA_PIXEL },
0035 { },
0036 };
0037
0038 static struct logicvc_of_property logicvc_of_properties[] = {
0039 [LOGICVC_OF_PROPERTY_DISPLAY_INTERFACE] = {
0040 .name = "xylon,display-interface",
0041 .sv = logicvc_of_display_interface_sv,
0042 .range = {
0043 LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS,
0044 LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS,
0045 },
0046 },
0047 [LOGICVC_OF_PROPERTY_DISPLAY_COLORSPACE] = {
0048 .name = "xylon,display-colorspace",
0049 .sv = logicvc_of_display_colorspace_sv,
0050 .range = {
0051 LOGICVC_DISPLAY_COLORSPACE_RGB,
0052 LOGICVC_DISPLAY_COLORSPACE_YUV444,
0053 },
0054 },
0055 [LOGICVC_OF_PROPERTY_DISPLAY_DEPTH] = {
0056 .name = "xylon,display-depth",
0057 .range = { 8, 24 },
0058 },
0059 [LOGICVC_OF_PROPERTY_ROW_STRIDE] = {
0060 .name = "xylon,row-stride",
0061 },
0062 [LOGICVC_OF_PROPERTY_DITHERING] = {
0063 .name = "xylon,dithering",
0064 .optional = true,
0065 },
0066 [LOGICVC_OF_PROPERTY_BACKGROUND_LAYER] = {
0067 .name = "xylon,background-layer",
0068 .optional = true,
0069 },
0070 [LOGICVC_OF_PROPERTY_LAYERS_CONFIGURABLE] = {
0071 .name = "xylon,layers-configurable",
0072 .optional = true,
0073 },
0074 [LOGICVC_OF_PROPERTY_LAYERS_COUNT] = {
0075 .name = "xylon,layers-count",
0076 },
0077 [LOGICVC_OF_PROPERTY_LAYER_DEPTH] = {
0078 .name = "xylon,layer-depth",
0079 .range = { 8, 24 },
0080 },
0081 [LOGICVC_OF_PROPERTY_LAYER_COLORSPACE] = {
0082 .name = "xylon,layer-colorspace",
0083 .sv = logicvc_of_layer_colorspace_sv,
0084 .range = {
0085 LOGICVC_LAYER_COLORSPACE_RGB,
0086 LOGICVC_LAYER_COLORSPACE_RGB,
0087 },
0088 },
0089 [LOGICVC_OF_PROPERTY_LAYER_ALPHA_MODE] = {
0090 .name = "xylon,layer-alpha-mode",
0091 .sv = logicvc_of_layer_alpha_mode_sv,
0092 .range = {
0093 LOGICVC_LAYER_ALPHA_LAYER,
0094 LOGICVC_LAYER_ALPHA_PIXEL,
0095 },
0096 },
0097 [LOGICVC_OF_PROPERTY_LAYER_BASE_OFFSET] = {
0098 .name = "xylon,layer-base-offset",
0099 },
0100 [LOGICVC_OF_PROPERTY_LAYER_BUFFER_OFFSET] = {
0101 .name = "xylon,layer-buffer-offset",
0102 },
0103 [LOGICVC_OF_PROPERTY_LAYER_PRIMARY] = {
0104 .name = "xylon,layer-primary",
0105 .optional = true,
0106 },
0107 };
0108
0109 static int logicvc_of_property_sv_value(struct logicvc_of_property_sv *sv,
0110 const char *string, u32 *value)
0111 {
0112 unsigned int i = 0;
0113
0114 while (sv[i].string) {
0115 if (!strcmp(sv[i].string, string)) {
0116 *value = sv[i].value;
0117 return 0;
0118 }
0119
0120 i++;
0121 }
0122
0123 return -EINVAL;
0124 }
0125
0126 int logicvc_of_property_parse_u32(struct device_node *of_node,
0127 unsigned int index, u32 *target)
0128 {
0129 struct logicvc_of_property *property;
0130 const char *string;
0131 u32 value;
0132 int ret;
0133
0134 if (index >= LOGICVC_OF_PROPERTY_MAXIMUM)
0135 return -EINVAL;
0136
0137 property = &logicvc_of_properties[index];
0138
0139 if (!property->optional &&
0140 !of_property_read_bool(of_node, property->name))
0141 return -ENODEV;
0142
0143 if (property->sv) {
0144 ret = of_property_read_string(of_node, property->name, &string);
0145 if (ret)
0146 return ret;
0147
0148 ret = logicvc_of_property_sv_value(property->sv, string,
0149 &value);
0150 if (ret)
0151 return ret;
0152 } else {
0153 ret = of_property_read_u32(of_node, property->name, &value);
0154 if (ret)
0155 return ret;
0156 }
0157
0158 if (property->range[0] || property->range[1])
0159 if (value < property->range[0] || value > property->range[1])
0160 return -ERANGE;
0161
0162 *target = value;
0163
0164 return 0;
0165 }
0166
0167 void logicvc_of_property_parse_bool(struct device_node *of_node,
0168 unsigned int index, bool *target)
0169 {
0170 struct logicvc_of_property *property;
0171
0172 if (index >= LOGICVC_OF_PROPERTY_MAXIMUM) {
0173
0174 *target = false;
0175 return;
0176 }
0177
0178 property = &logicvc_of_properties[index];
0179 *target = of_property_read_bool(of_node, property->name);
0180 }
0181
0182 bool logicvc_of_node_is_layer(struct device_node *of_node)
0183 {
0184 return !of_node_cmp(of_node->name, "layer");
0185 }