1 #include <linux/ctype.h>
2 #include <linux/string.h>
3 #include <linux/display-sys.h>
4 #include <linux/interrupt.h>
7 static int hdmi_get_enable(struct rk_display_device *device)
9 struct hdmi *hdmi = device->priv_data;
12 mutex_lock(&hdmi->enable_mutex);
13 enable = hdmi->enable;
14 mutex_unlock(&hdmi->enable_mutex);
19 static int hdmi_set_enable(struct rk_display_device *device, int enable)
21 struct hdmi *hdmi = device->priv_data;
23 mutex_lock(&hdmi->enable_mutex);
24 if (hdmi->enable == enable) {
25 mutex_unlock(&hdmi->enable_mutex);
28 hdmi->enable = enable;
31 mutex_unlock(&hdmi->enable_mutex);
37 disable_irq(hdmi->irq);
38 mutex_unlock(&hdmi->enable_mutex);
39 hdmi->command = HDMI_CONFIG_ENABLE;
40 queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
43 enable_irq(hdmi->irq);
44 queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
45 mutex_unlock(&hdmi->enable_mutex);
50 static int hdmi_get_status(struct rk_display_device *device)
52 struct hdmi *hdmi = device->priv_data;
54 if (hdmi->hotplug == HDMI_HPD_ACTIVED)
60 static int hdmi_get_modelist(struct rk_display_device *device,
61 struct list_head **modelist)
63 struct hdmi *hdmi = device->priv_data;
67 *modelist = &hdmi->edid.modelist;
71 static int hdmi_set_mode(struct rk_display_device *device,
72 struct fb_videomode *mode)
74 struct hdmi *hdmi = device->priv_data;
75 int vic = hdmi_videomode_to_vic(mode);
77 hdmi->autoconfig = HDMI_DISABLE;
78 if (vic && hdmi->vic != vic) {
82 hdmi->command = HDMI_CONFIG_VIDEO;
83 init_completion(&hdmi->complete);
85 queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
86 wait_for_completion_interruptible_timeout(&hdmi->complete,
93 static int hdmi_get_mode(struct rk_display_device *device,
94 struct fb_videomode *mode)
96 struct hdmi *hdmi = device->priv_data;
97 struct fb_videomode *vmode;
102 vmode = (struct fb_videomode *)hdmi_vic_to_videomode(hdmi->vic);
103 if (unlikely(vmode == NULL))
109 static int hdmi_set_scale(struct rk_display_device *device, int direction,
112 struct hdmi *hdmi = device->priv_data;
114 if (!hdmi || value < 0 || value > 100)
120 if (direction == DISPLAY_SCALE_X)
121 hdmi->xscale = value;
122 else if (direction == DISPLAY_SCALE_Y)
123 hdmi->yscale = value;
126 rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id);
130 static int hdmi_get_scale(struct rk_display_device *device, int direction)
132 struct hdmi *hdmi = device->priv_data;
137 if (direction == DISPLAY_SCALE_X)
139 else if (direction == DISPLAY_SCALE_Y)
144 static int hdmi_set_debug(struct rk_display_device *device, int cmd)
146 struct hdmi *hdmi = device->priv_data;
150 if (hdmi->ops && hdmi->ops->hdmi_debug)
151 hdmi->ops->hdmi_debug(hdmi,cmd);
155 //CEA 861-E: Audio Coding Type
156 //sync width enum hdmi_audio_type
157 static const char* const sAudioFormatStr[] = {
159 "LPCM", //HDMI_AUDIO_LPCM = 1,
160 "AC3", //HDMI_AUDIO_AC3,
161 "MPEG1", //HDMI_AUDIO_MPEG1,
162 "MP3", //HDMI_AUDIO_MP3,
163 "MPEG2", //HDMI_AUDIO_MPEG2,
164 "AAC-LC", //HDMI_AUDIO_AAC_LC, //AAC
165 "DTS", //HDMI_AUDIO_DTS,
166 "ATARC", //HDMI_AUDIO_ATARC,
167 "DSD", //HDMI_AUDIO_DSD, //One bit Audio
168 "E-AC3", //HDMI_AUDIO_E_AC3,
169 "DTS-HD", //HDMI_AUDIO_DTS_HD,
170 "MLP", //HDMI_AUDIO_MLP,
171 "DST", //HDMI_AUDIO_DST,
172 "WMA-PRO", //HDMI_AUDIO_WMA_PRO
175 static int hdmi_get_edidaudioinfo(struct rk_display_device *device, char *audioinfo, int len)
177 struct hdmi *hdmi = device->priv_data;
180 struct hdmi_audio *audio;
184 memset(audioinfo, 0x00, len);
185 mutex_lock(&hdmi->lock);
186 //printk("hdmi:edid: audio_num: %d\n", hdmi->edid.audio_num);
187 for(i = 0; i < hdmi->edid.audio_num; i++)
189 audio = &(hdmi->edid.audio[i]);
190 if(audio->type<1 || audio->type>HDMI_AUDIO_WMA_PRO){
191 printk("audio type: unsupported.");
194 size = strlen(sAudioFormatStr[audio->type]);
195 //printk("size: %d, type: %s\n", size, sAudioFormatStr[audio->type]);
196 memcpy(audioinfo, sAudioFormatStr[audio->type], size);
198 audioinfo += (size+1);
200 mutex_unlock(&hdmi->lock);
205 static int hdmi_get_monspecs(struct rk_display_device *device, struct fb_monspecs *monspecs)
207 struct hdmi *hdmi = device->priv_data;
212 mutex_lock(&hdmi->lock);
214 *monspecs = *(hdmi->edid.specs);
215 mutex_unlock(&hdmi->lock);
219 struct rk_display_ops hdmi_display_ops = {
220 .setenable = hdmi_set_enable,
221 .getenable = hdmi_get_enable,
222 .getstatus = hdmi_get_status,
223 .getmodelist = hdmi_get_modelist,
224 .setmode = hdmi_set_mode,
225 .getmode = hdmi_get_mode,
226 .setscale = hdmi_set_scale,
227 .getscale = hdmi_get_scale,
228 .setdebug = hdmi_set_debug,
229 .getedidaudioinfo = hdmi_get_edidaudioinfo,
230 .getmonspecs = hdmi_get_monspecs,
234 static int hdmi_display_probe(struct rk_display_device *device, void *devdata)
236 device->owner = THIS_MODULE;
237 strcpy(device->type, "HDMI");
238 device->priority = DISPLAY_PRIORITY_HDMI;
240 device->name = kmalloc(strlen(name), GFP_KERNEL);
242 strcpy(device->name, name);
244 device->priv_data = devdata;
245 device->ops = &hdmi_display_ops;
249 static struct rk_display_driver display_hdmi = {
250 .probe = hdmi_display_probe,
253 #ifdef CONFIG_DRM_ROCKCHIP
254 extern void rk_drm_display_register(struct rk_display_ops *extend_ops,
255 void *displaydata, int type);
258 void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent)
261 rk_display_device_register(&display_hdmi, parent, hdmi);
262 #ifdef CONFIG_DRM_ROCKCHIP
263 rk_drm_display_register(&hdmi_display_ops, hdmi, SCREEN_HDMI);
267 void hdmi_unregister_display_sysfs(struct hdmi *hdmi)
270 rk_display_device_unregister(hdmi->ddev);