1 #include <linux/module.h>
2 #include <linux/ctype.h>
5 #include <linux/kdev_t.h>
6 #include <linux/display-sys.h>
8 static struct list_head main_display_device_list;
9 static struct list_head aux_display_device_list;
11 static ssize_t name_show(struct device *dev,
12 struct device_attribute *attr, char *buf)
14 struct rk_display_device *dsp = dev_get_drvdata(dev);
16 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
19 static DEVICE_ATTR_RO(name);
21 static ssize_t type_show(struct device *dev,
22 struct device_attribute *attr, char *buf)
24 struct rk_display_device *dsp = dev_get_drvdata(dev);
26 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
29 static DEVICE_ATTR_RO(type);
31 static ssize_t property_show(struct device *dev,
32 struct device_attribute *attr, char *buf)
34 struct rk_display_device *dsp = dev_get_drvdata(dev);
36 return snprintf(buf, PAGE_SIZE, "%d\n", dsp->property);
39 static DEVICE_ATTR_RO(property);
41 static ssize_t enable_show(struct device *dev,
42 struct device_attribute *attr, char *buf)
44 struct rk_display_device *dsp = dev_get_drvdata(dev);
47 if (dsp->ops && dsp->ops->getenable)
48 enable = dsp->ops->getenable(dsp);
51 return snprintf(buf, PAGE_SIZE, "%d\n", enable);
54 static ssize_t enable_store(struct device *dev,
55 struct device_attribute *attr,
56 const char *buf, size_t size)
58 struct rk_display_device *dsp = dev_get_drvdata(dev);
61 if (kstrtoint(buf, 0, &enable))
63 if (dsp->ops && dsp->ops->setenable)
64 dsp->ops->setenable(dsp, enable);
68 static DEVICE_ATTR_RW(enable);
70 static ssize_t connect_show(struct device *dev,
71 struct device_attribute *attr, char *buf)
73 struct rk_display_device *dsp = dev_get_drvdata(dev);
76 if (dsp->ops && dsp->ops->getstatus)
77 connect = dsp->ops->getstatus(dsp);
80 return snprintf(buf, PAGE_SIZE, "%d\n", connect);
83 static DEVICE_ATTR_RO(connect);
85 static int mode_string(char *buf, unsigned int offset,
86 const struct fb_videomode *mode)
91 pr_err("%s parameter error\n", __func__);
94 if (mode->xres == 0 && mode->yres == 0)
95 return snprintf(&buf[offset], PAGE_SIZE - offset, "auto\n");
96 if (mode->vmode & FB_VMODE_INTERLACED)
98 if (mode->vmode & FB_VMODE_DOUBLE)
101 return snprintf(&buf[offset], PAGE_SIZE - offset,
102 "%dx%d%c-%d(YCbCr420)\n",
103 mode->xres, mode->yres, v, mode->refresh);
105 return snprintf(&buf[offset], PAGE_SIZE - offset,
107 mode->xres, mode->yres, v, mode->refresh);
110 static ssize_t modes_show(struct device *dev,
111 struct device_attribute *attr, char *buf)
113 struct rk_display_device *dsp = dev_get_drvdata(dev);
114 struct list_head *modelist, *pos;
115 struct display_modelist *display_modelist;
116 const struct fb_videomode *mode;
119 mutex_lock(&dsp->lock);
120 if (dsp->ops && dsp->ops->getmodelist) {
121 if (dsp->ops->getmodelist(dsp, &modelist)) {
122 mutex_unlock(&dsp->lock);
126 mutex_unlock(&dsp->lock);
130 if (dsp->priority == DISPLAY_PRIORITY_HDMI)
131 i += snprintf(buf, PAGE_SIZE, "auto\n");
133 list_for_each(pos, modelist) {
134 display_modelist = list_entry(pos,
135 struct display_modelist,
137 mode = &display_modelist->mode;
138 i += mode_string(buf, i, mode);
140 mutex_unlock(&dsp->lock);
144 static DEVICE_ATTR_RO(modes);
146 static ssize_t mode_show(struct device *dev,
147 struct device_attribute *attr, char *buf)
149 struct rk_display_device *dsp = dev_get_drvdata(dev);
150 struct fb_videomode mode;
152 if (dsp->ops && dsp->ops->getmode)
153 if (dsp->ops->getmode(dsp, &mode) == 0)
154 return mode_string(buf, 0, &mode);
158 static ssize_t mode_store(struct device *dev,
159 struct device_attribute *attr,
160 const char *buf, size_t count)
162 struct rk_display_device *dsp = dev_get_drvdata(dev);
164 struct list_head *modelist, *pos;
165 struct display_modelist *display_modelist;
166 struct fb_videomode *mode;
169 mutex_lock(&dsp->lock);
170 if (!memcmp(buf, "auto", 4)) {
171 if (dsp->ops && dsp->ops->setmode)
172 dsp->ops->setmode(dsp, NULL);
173 mutex_unlock(&dsp->lock);
177 if (dsp->ops && dsp->ops->getmodelist) {
178 if (dsp->ops && dsp->ops->getmodelist) {
179 if (dsp->ops->getmodelist(dsp, &modelist)) {
180 mutex_unlock(&dsp->lock);
184 list_for_each(pos, modelist) {
185 display_modelist = list_entry(pos,
186 struct display_modelist,
188 mode = &display_modelist->mode;
189 i = mode_string(mstr, 0, mode);
190 if (strncmp(mstr, buf, max(count, i)) == 0) {
191 if (dsp->ops && dsp->ops->setmode)
192 dsp->ops->setmode(dsp, mode);
193 mutex_unlock(&dsp->lock);
198 mutex_unlock(&dsp->lock);
202 static DEVICE_ATTR_RW(mode);
204 static ssize_t scale_show(struct device *dev,
205 struct device_attribute *attr,
208 struct rk_display_device *dsp = dev_get_drvdata(dev);
211 if (dsp->ops && dsp->ops->getscale) {
212 xscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_X);
213 yscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_Y);
214 if (xscale && yscale)
215 return snprintf(buf, PAGE_SIZE,
216 "xscale=%d yscale=%d\n",
222 static ssize_t scale_store(struct device *dev,
223 struct device_attribute *attr,
224 const char *buf, size_t count)
226 struct rk_display_device *dsp = dev_get_drvdata(dev);
229 if (dsp->ops && dsp->ops->setscale) {
230 if (!strncmp(buf, "xscale", 6)) {
231 if (!kstrtoint(buf, 0, &scale))
232 dsp->ops->setscale(dsp,
235 } else if (!strncmp(buf, "yscale", 6)) {
236 if (!kstrtoint(buf, 0, &scale))
237 dsp->ops->setscale(dsp,
241 if (!kstrtoint(buf, 0, &scale)) {
242 dsp->ops->setscale(dsp,
245 dsp->ops->setscale(dsp,
255 static DEVICE_ATTR_RW(scale);
257 static ssize_t mode3d_show(struct device *dev,
258 struct device_attribute *attr, char *buf)
260 struct rk_display_device *dsp = dev_get_drvdata(dev);
261 struct list_head *modelist, *pos;
262 struct display_modelist *display_modelist;
263 struct fb_videomode mode;
264 int i = 0, cur_3d_mode = -1;
266 int mode_strlen, format_3d;
268 mutex_lock(&dsp->lock);
269 if (dsp->ops && dsp->ops->getmodelist) {
270 if (dsp->ops->getmodelist(dsp, &modelist)) {
271 mutex_unlock(&dsp->lock);
275 mutex_unlock(&dsp->lock);
279 if (dsp->ops && dsp->ops->getmode) {
280 if (dsp->ops->getmode(dsp, &mode)) {
281 mutex_unlock(&dsp->lock);
285 mutex_unlock(&dsp->lock);
289 list_for_each(pos, modelist) {
290 display_modelist = list_entry(pos,
291 struct display_modelist,
293 if (!fb_mode_is_equal(&mode, &display_modelist->mode))
294 display_modelist = NULL;
298 if (display_modelist)
299 i = snprintf(buf, PAGE_SIZE, "3dmodes=%d\n",
300 display_modelist->format_3d);
302 i = snprintf(buf, PAGE_SIZE, "3dmodes=0\n");
304 if (dsp->ops && dsp->ops->get3dmode)
305 cur_3d_mode = dsp->ops->get3dmode(dsp);
306 i += snprintf(buf + i, PAGE_SIZE - i, "cur3dmode=%d\n", cur_3d_mode);
308 list_for_each(pos, modelist) {
309 display_modelist = list_entry(pos,
310 struct display_modelist,
312 mode_strlen = mode_string(mode_str, 0,
313 &display_modelist->mode);
314 mode_str[mode_strlen - 1] = 0;
315 format_3d = display_modelist->format_3d;
316 i += snprintf(buf + i, PAGE_SIZE, "%s,%d\n",
317 mode_str, format_3d);
319 mutex_unlock(&dsp->lock);
323 static ssize_t mode3d_store(struct device *dev,
324 struct device_attribute *attr,
325 const char *buf, size_t count)
327 struct rk_display_device *dsp = dev_get_drvdata(dev);
330 mutex_lock(&dsp->lock);
331 if (dsp->ops && dsp->ops->set3dmode) {
332 if (!kstrtoint(buf, 0, &mode))
333 dsp->ops->set3dmode(dsp, mode);
334 mutex_unlock(&dsp->lock);
337 mutex_unlock(&dsp->lock);
341 static DEVICE_ATTR_RW(mode3d);
343 static ssize_t color_show(struct device *dev,
344 struct device_attribute *attr, char *buf)
346 struct rk_display_device *dsp = dev_get_drvdata(dev);
349 mutex_lock(&dsp->lock);
350 if (dsp->ops && dsp->ops->getcolor)
351 ret = dsp->ops->getcolor(dsp, buf);
352 mutex_unlock(&dsp->lock);
356 static ssize_t color_store(struct device *dev,
357 struct device_attribute *attr,
358 const char *buf, size_t count)
360 struct rk_display_device *dsp = dev_get_drvdata(dev);
362 mutex_lock(&dsp->lock);
363 if (dsp->ops && dsp->ops->setcolor) {
364 if (!dsp->ops->setcolor(dsp, buf, count)) {
365 mutex_unlock(&dsp->lock);
369 mutex_unlock(&dsp->lock);
373 static DEVICE_ATTR_RW(color);
375 static ssize_t audioinfo_show(struct device *dev,
376 struct device_attribute *attr,
379 struct rk_display_device *dsp = dev_get_drvdata(dev);
383 mutex_lock(&dsp->lock);
384 if (dsp->ops && dsp->ops->getedidaudioinfo) {
385 ret = dsp->ops->getedidaudioinfo(dsp, audioinfo, 200);
387 mutex_unlock(&dsp->lock);
388 return snprintf(buf, PAGE_SIZE, "%s\n", audioinfo);
391 mutex_unlock(&dsp->lock);
395 static DEVICE_ATTR_RO(audioinfo);
397 static ssize_t monspecs_show(struct device *dev,
398 struct device_attribute *attr, char *buf)
400 struct rk_display_device *dsp = dev_get_drvdata(dev);
401 struct fb_monspecs monspecs;
404 mutex_lock(&dsp->lock);
405 if (dsp->ops && dsp->ops->getmonspecs) {
406 ret = dsp->ops->getmonspecs(dsp, &monspecs);
408 mutex_unlock(&dsp->lock);
409 memcpy(buf, &monspecs, sizeof(struct fb_monspecs));
410 return sizeof(struct fb_monspecs);
413 mutex_unlock(&dsp->lock);
417 static DEVICE_ATTR_RO(monspecs);
419 static ssize_t debug_show(struct device *dev,
420 struct device_attribute *attr, char *buf)
422 struct rk_display_device *dsp = dev_get_drvdata(dev);
425 mutex_lock(&dsp->lock);
426 if (dsp->ops && dsp->ops->getdebug)
427 ret = dsp->ops->getdebug(dsp, buf);
428 mutex_unlock(&dsp->lock);
432 static ssize_t debug_store(struct device *dev,
433 struct device_attribute *attr,
434 const char *buf, size_t count)
436 int cmd, ret = -EINVAL;
437 struct rk_display_device *dsp = dev_get_drvdata(dev);
439 mutex_lock(&dsp->lock);
440 if (dsp->ops && dsp->ops->setdebug) {
441 if (kstrtoint(buf, 0, &cmd) == 0)
442 dsp->ops->setdebug(dsp, cmd);
445 mutex_unlock(&dsp->lock);
449 static DEVICE_ATTR_RW(debug);
451 static ssize_t prop_show(struct device *dev,
452 struct device_attribute *attr, char *buf)
454 struct rk_display_device *dsp = dev_get_drvdata(dev);
457 mutex_lock(&dsp->lock);
458 if (dsp->ops && dsp->ops->getvrinfo)
459 ret = dsp->ops->getvrinfo(dsp, buf);
460 mutex_unlock(&dsp->lock);
465 static DEVICE_ATTR_RO(prop);
467 static struct attribute *display_device_attrs[] = {
470 &dev_attr_property.attr,
471 &dev_attr_enable.attr,
472 &dev_attr_connect.attr,
473 &dev_attr_modes.attr,
475 &dev_attr_scale.attr,
476 &dev_attr_mode3d.attr,
477 &dev_attr_color.attr,
478 &dev_attr_audioinfo.attr,
479 &dev_attr_monspecs.attr,
480 &dev_attr_debug.attr,
485 ATTRIBUTE_GROUPS(display_device);
487 static int display_suspend(struct device *dev, pm_message_t state)
489 struct rk_display_device *dsp = dev_get_drvdata(dev);
491 mutex_lock(&dsp->lock);
492 if (likely(dsp->driver->suspend))
493 dsp->driver->suspend(dsp, state);
494 mutex_unlock(&dsp->lock);
498 static int display_resume(struct device *dev)
500 struct rk_display_device *dsp = dev_get_drvdata(dev);
502 mutex_lock(&dsp->lock);
503 if (likely(dsp->driver->resume))
504 dsp->driver->resume(dsp);
505 mutex_unlock(&dsp->lock);
509 int display_add_videomode(const struct fb_videomode *mode,
510 struct list_head *head)
512 struct list_head *pos;
513 struct display_modelist *modelist;
514 struct fb_videomode *m;
517 list_for_each(pos, head) {
518 modelist = list_entry(pos, struct display_modelist, list);
520 if (fb_mode_is_equal(m, mode)) {
526 modelist = kmalloc(sizeof(*modelist),
531 modelist->mode = *mode;
532 list_add(&modelist->list, head);
537 void rk_display_device_enable(struct rk_display_device *ddev)
539 struct list_head *pos, *head;
540 struct rk_display_device *dev = NULL, *dev_enabled = NULL;
541 struct rk_display_device *dev_enable = NULL;
542 int enable = 0, connect;
544 if (ddev->property == DISPLAY_MAIN)
545 head = &main_display_device_list;
547 head = &aux_display_device_list;
549 list_for_each(pos, head) {
550 dev = list_entry(pos, struct rk_display_device, list);
551 enable = dev->ops->getenable(dev);
552 connect = dev->ops->getstatus(dev);
558 /* If no device is connected, enable highest priority device. */
560 dev->ops->setenable(dev, 1);
564 if (dev_enable == dev_enabled) {
565 if (dev_enable != ddev)
566 ddev->ops->setenable(ddev, 0);
569 dev_enabled->priority != DISPLAY_PRIORITY_HDMI)
570 dev_enabled->ops->setenable(dev_enabled, 0);
571 dev_enable->ops->setenable(dev_enable, 1);
574 EXPORT_SYMBOL(rk_display_device_enable);
576 void rk_display_device_enable_other(struct rk_display_device *ddev)
578 #ifndef CONFIG_DISPLAY_AUTO_SWITCH
581 struct list_head *pos, *head;
582 struct rk_display_device *dev;
585 if (ddev->property == DISPLAY_MAIN)
586 head = &main_display_device_list;
588 head = &aux_display_device_list;
590 list_for_each_prev(pos, head) {
591 dev = list_entry(pos, struct rk_display_device, list);
593 connect = dev->ops->getstatus(dev);
595 dev->ops->setenable(dev, 1);
602 EXPORT_SYMBOL(rk_display_device_enable_other);
604 void rk_display_device_disable_other(struct rk_display_device *ddev)
606 #ifndef CONFIG_DISPLAY_AUTO_SWITCH
609 struct list_head *pos, *head;
610 struct rk_display_device *dev;
613 if (ddev->property == DISPLAY_MAIN)
614 head = &main_display_device_list;
616 head = &aux_display_device_list;
618 list_for_each(pos, head) {
619 dev = list_entry(pos, struct rk_display_device, list);
621 enable = dev->ops->getenable(dev);
623 dev->ops->setenable(dev, 0);
626 ddev->ops->setenable(ddev, 1);
629 EXPORT_SYMBOL(rk_display_device_disable_other);
631 void rk_display_device_select(int property, int priority)
633 struct list_head *pos, *head;
634 struct rk_display_device *dev;
635 int enable, found = 0;
637 if (property == DISPLAY_MAIN)
638 head = &main_display_device_list;
640 head = &aux_display_device_list;
642 list_for_each(pos, head) {
643 dev = list_entry(pos, struct rk_display_device, list);
644 if (dev->priority == priority)
649 pr_err("[%s] select display interface %d not exist\n",
654 list_for_each(pos, head) {
655 dev = list_entry(pos, struct rk_display_device, list);
656 enable = dev->ops->getenable(dev);
657 if (dev->priority == priority) {
659 dev->ops->setenable(dev, 1);
661 dev->ops->setenable(dev, 0);
665 EXPORT_SYMBOL(rk_display_device_select);
666 static struct mutex allocated_dsp_lock;
667 static DEFINE_IDR(allocated_dsp);
668 static struct class *display_class;
670 struct rk_display_device
671 *rk_display_device_register(struct rk_display_driver *driver,
672 struct device *parent, void *devdata)
674 struct rk_display_device *new_dev = NULL;
677 if (unlikely(!driver))
680 new_dev = kzalloc(sizeof(*new_dev), GFP_KERNEL);
681 if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
682 /* Reserve the index for this display */
683 mutex_lock(&allocated_dsp_lock);
684 new_dev->idx = idr_alloc(&allocated_dsp, new_dev,
686 mutex_unlock(&allocated_dsp_lock);
688 if (new_dev->idx >= 0) {
689 struct list_head *pos, *head;
690 struct rk_display_device *dev;
693 head = &main_display_device_list;
694 list_for_each_entry(dev, head, list) {
695 if (strcmp(dev->type, new_dev->type) == 0)
698 head = &aux_display_device_list;
699 list_for_each_entry(dev, head, list) {
700 if (strcmp(dev->type, new_dev->type) == 0)
705 device_create(display_class, parent,
706 MKDEV(0, 0), new_dev,
707 "%s", new_dev->type);
710 device_create(display_class, parent,
711 MKDEV(0, 0), new_dev,
712 "%s%d", new_dev->type, i);
714 if (!IS_ERR(new_dev->dev)) {
715 new_dev->parent = parent;
716 new_dev->driver = driver;
718 new_dev->dev->driver = parent->driver;
719 mutex_init(&new_dev->lock);
720 /* Add new device to display device list. */
721 if (new_dev->property == DISPLAY_MAIN)
722 head = &main_display_device_list;
724 head = &aux_display_device_list;
726 list_for_each(pos, head) {
729 struct rk_display_device,
731 if (dev->priority > new_dev->priority)
734 list_add_tail(&new_dev->list, pos);
737 mutex_lock(&allocated_dsp_lock);
738 idr_remove(&allocated_dsp, new_dev->idx);
739 mutex_unlock(&allocated_dsp_lock);
746 EXPORT_SYMBOL(rk_display_device_register);
748 void rk_display_device_unregister(struct rk_display_device *ddev)
753 mutex_lock(&ddev->lock);
754 device_unregister(ddev->dev);
755 mutex_unlock(&ddev->lock);
756 /* Mark device index as available */
757 mutex_lock(&allocated_dsp_lock);
758 idr_remove(&allocated_dsp, ddev->idx);
759 mutex_unlock(&allocated_dsp_lock);
760 list_del(&ddev->list);
763 EXPORT_SYMBOL(rk_display_device_unregister);
765 static int __init rk_display_class_init(void)
767 display_class = class_create(THIS_MODULE, "display");
768 if (IS_ERR(display_class)) {
769 pr_err("Failed to create display class\n");
770 display_class = NULL;
773 display_class->dev_groups = display_device_groups;
774 display_class->suspend = display_suspend;
775 display_class->resume = display_resume;
776 mutex_init(&allocated_dsp_lock);
777 INIT_LIST_HEAD(&main_display_device_list);
778 INIT_LIST_HEAD(&aux_display_device_list);
782 static void __exit rk_display_class_exit(void)
784 class_destroy(display_class);
787 subsys_initcall(rk_display_class_init);
788 module_exit(rk_display_class_exit);
790 MODULE_AUTHOR("zhengyang@rock-chips.com");
791 MODULE_DESCRIPTION("Driver for rk display device");
792 MODULE_LICENSE("GPL");